Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt
-
-
- Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
- eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
- voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
- clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
- amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
- nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
- sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
- Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor
- sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
- diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
- sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
- Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor
- sit amet.
-
-
-
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
+ eirmod tempor invidunt
+
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
+ eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
+ voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
+ clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
+ amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
+ nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed
+ diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
+ Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor
+ sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
+ diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+ erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
+ rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
+ dolor sit amet.
+
-
-
+ video.addEventListener("pause", event => {
+ document.querySelector(".playbackState").innerHTML =
+ "Media file is paused";
+ });
+
+
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt
index ac40972db6..fb8fe67616 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt
@@ -46,6 +46,7 @@ import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
import org.mozilla.fenix.helpers.Constants.PackageName.PIXEL_LAUNCHER
import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP
import org.mozilla.fenix.helpers.Constants.TAG
+import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper.appContext
@@ -586,4 +587,13 @@ object AppAndSystemHelper {
e.printStackTrace()
}
}
+
+ fun dismissSetAsDefaultBrowserOnboardingDialog() {
+ Log.i(TAG, "dismissSetAsDefaultBrowserOnboardingDialog: Detected API ${Build.VERSION.SDK_INT}")
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ Log.i(TAG, "dismissSetAsDefaulltBrowserOnboardingDialog: Trying to click the \"Cancel\" dialog button.")
+ itemWithResIdContainingText("android:id/button2", "Cancel").click()
+ Log.i(TAG, "dismissSetAsDefaulltBrowserOnboardingDialog: Clicked the \"Cancel\" dialog button.")
+ }
+ }
}
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark.js b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark.js
index e1210bd24e..766a033b3a 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark.js
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark.js
@@ -8,19 +8,17 @@
*/
EnableEngines(["bookmarks"]);
-var phases = { "phase1": "profile1" };
-
+var phases = { phase1: "profile1" };
// expected bookmark state
var bookmarksCreated = {
-"mobile": [{
- uri: "http://www.example.com/",
- title: "Example Domain"}]
+ mobile: [
+ {
+ uri: "http://www.example.com/",
+ title: "Example Domain",
+ },
+ ],
};
// sync and verify bookmarks
-Phase("phase1", [
- [Sync],
- [Bookmarks.add, bookmarksCreated],
- [Sync]
-]);
\ No newline at end of file
+Phase("phase1", [[Sync], [Bookmarks.add, bookmarksCreated], [Sync]]);
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark_desktop.js b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark_desktop.js
index a6a42aa6d0..69489f84a7 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark_desktop.js
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_bookmark_desktop.js
@@ -8,18 +8,17 @@
*/
EnableEngines(["bookmarks"]);
-var phases = { "phase1": "profile1" };
-
+var phases = { phase1: "profile1" };
// expected bookmark state
var bookmarksExpected = {
-"mobile": [{
- uri: "http://www.example.com/",
- title: "Example Domain"}]
+ mobile: [
+ {
+ uri: "http://www.example.com/",
+ title: "Example Domain",
+ },
+ ],
};
// sync and verify bookmarks
-Phase("phase1", [
- [Sync],
- [Bookmarks.verify, bookmarksExpected],
-]);
+Phase("phase1", [[Sync], [Bookmarks.verify, bookmarksExpected]]);
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history.js b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history.js
index 8b915945e2..9aa96f4aef 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history.js
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history.js
@@ -8,26 +8,18 @@
*/
EnableEngines(["history"]);
-var phases = { "phase1": "profile1" };
-
+var phases = { phase1: "profile1" };
// expected history state
var historyCreated = [
- { uri: "http://www.example.com/",
- visits: [
- { type: 1 ,
- date: 0
- },
- { type: 2,
- date: -1
- }
- ]
- }
+ {
+ uri: "http://www.example.com/",
+ visits: [
+ { type: 1, date: 0 },
+ { type: 2, date: -1 },
+ ],
+ },
];
// sync and verify history
-Phase("phase1", [
- [Sync],
- [History.add, historyCreated],
- [Sync]
-]);
+Phase("phase1", [[Sync], [History.add, historyCreated], [Sync]]);
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history_desktop.js b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history_desktop.js
index 5dfdd1aa47..7cf2acaccb 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history_desktop.js
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_history_desktop.js
@@ -8,21 +8,12 @@
*/
EnableEngines(["history"]);
-var phases = { "phase1": "profile1" };
-
+var phases = { phase1: "profile1" };
// expected history state
var historyExpected = [
- { uri: "http://www.example.com/",
- visits: [
- { type: 1 },
- { type: 2 }
- ]
- }
+ { uri: "http://www.example.com/", visits: [{ type: 1 }, { type: 2 }] },
];
// sync and verify history
-Phase("phase1", [
- [Sync],
- [History.verify, historyExpected]
-]);
+Phase("phase1", [[Sync], [History.verify, historyExpected]]);
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_logins.js b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_logins.js
index 16eb4bcf34..bc1d1e1071 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_logins.js
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/test_logins.js
@@ -8,11 +8,11 @@
*/
EnableEngines(["passwords"]);
-var phases = { "phase1": "profile1" };
-
+var phases = { phase1: "profile1" };
// expected tabs state
-var password_list = [{
+var password_list = [
+ {
hostname: "https://accounts.google.com",
submitURL: "https://accounts.google.com/signin/challenge/sl/password",
realm: null,
@@ -20,11 +20,8 @@ var password_list = [{
password: "test15mz",
usernameField: "Email",
passwordField: "Passwd",
- }];
+ },
+];
// sync and verify tabs
-Phase("phase1", [
- [Sync],
- [Passwords.add, password_list],
- [Sync]
-]);
\ No newline at end of file
+Phase("phase1", [[Sync], [Passwords.add, password_list], [Sync]]);
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt
index 96ca6ad724..d575521a5d 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt
@@ -9,7 +9,6 @@ import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import androidx.test.espresso.Espresso.pressBack
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import kotlinx.coroutines.runBlocking
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
@@ -237,7 +236,6 @@ class BookmarksTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1919261
- @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test
fun verifyOpenAllInNewTabsOptionTest() {
val webPages = listOf(
@@ -261,11 +259,6 @@ class BookmarksTest : TestSetup() {
createBookmark(webPages[1].url, "root")
createBookmark(webPages[2].url, "root")
createBookmark(webPages[3].url, "sub")
- }.openTabDrawer {
- closeTab()
- }
-
- browserScreen {
}.openThreeDotMenu {
}.openBookmarks {
}.openThreeDotMenu("root") {
@@ -281,7 +274,6 @@ class BookmarksTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1919262
- @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test
fun verifyOpenAllInPrivateTabsTest() {
val webPages = listOf(
@@ -301,11 +293,6 @@ class BookmarksTest : TestSetup() {
browserScreen {
createBookmark(webPages[0].url, "root")
createBookmark(webPages[1].url, "sub")
- }.openTabDrawer {
- closeTab()
- }
-
- browserScreen {
}.openThreeDotMenu {
}.openBookmarks {
}.openThreeDotMenu("root") {
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt
index 398533830a..995e43f794 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt
@@ -233,11 +233,6 @@ class ComposeBookmarksTest : TestSetup() {
createBookmark(webPages[1].url, "root")
createBookmark(webPages[2].url, "root")
createBookmark(webPages[3].url, "sub")
- }.openComposeTabDrawer(activityTestRule) {
- closeTab()
- }
-
- browserScreen {
}.openThreeDotMenu {
}.openBookmarks {
}.openThreeDotMenu("root") {
@@ -272,11 +267,6 @@ class ComposeBookmarksTest : TestSetup() {
browserScreen {
createBookmark(webPages[0].url, "root")
createBookmark(webPages[1].url, "sub")
- }.openComposeTabDrawer(activityTestRule) {
- closeTab()
- }
-
- browserScreen {
}.openThreeDotMenu {
}.openBookmarks {
}.openThreeDotMenu("root") {
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCrashReportingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCrashReportingTest.kt
index e815972900..979824f2f8 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCrashReportingTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCrashReportingTest.kt
@@ -5,7 +5,6 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
@@ -48,7 +47,6 @@ class ComposeCrashReportingTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2336134
- @Ignore("Test failure caused by: https://github.com/mozilla-mobile/fenix/issues/19964")
@Test
fun restoreTabFromTabCrashedReporterTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt
index d3b17f57d9..2268825d3a 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt
@@ -7,7 +7,6 @@ package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import androidx.test.espresso.Espresso.pressBack
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
@@ -155,7 +154,6 @@ class ComposeHistoryTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339696
- @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test
fun openMultipleSelectedHistoryItemsInANewTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt
index eaa76b1481..30f1ea8dc5 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt
@@ -55,7 +55,7 @@ class ComposeSearchTest : TestSetup() {
private lateinit var searchMockServer: MockWebServer
private val queryString: String = "firefox"
private val generalEnginesList = listOf("DuckDuckGo", "Google", "Bing")
- private val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
+ private val topicEnginesList = listOf("Wikipedia", "eBay")
@get:Rule
val activityTestRule = AndroidComposeTestRule(
@@ -111,7 +111,7 @@ class ComposeSearchTest : TestSetup() {
verifySearchToolbar(isDisplayed = true)
clickSearchSelectorButton()
verifySearchShortcutListContains(
- "DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay",
+ "DuckDuckGo", "Google", "Wikipedia", "Bing", "eBay",
"Bookmarks", "Tabs", "History", "Search settings",
)
}
@@ -153,7 +153,7 @@ class ComposeSearchTest : TestSetup() {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154196
@Test
fun verifySearchPlaceholderForTopicSpecificSearchEnginesTest() {
- val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
+ val topicEnginesList = listOf("Wikipedia", "eBay")
topicEnginesList.forEach {
homeScreen {
@@ -229,7 +229,7 @@ class ComposeSearchTest : TestSetup() {
@SmokeTest
@Test
fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() {
- val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay")
+ val enginesList = listOf("DuckDuckGo", "Google", "Wikipedia", "Bing", "eBay")
enginesList.forEach {
homeScreen {
@@ -303,13 +303,12 @@ class ComposeSearchTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1592229
- @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test
fun verifyAPageIsAddedToASearchGroupOnlyOnceTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url
val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url
val originPageUrl =
- "http://localhost:${searchMockServer.port}/pages/searchResults.html?search=test%20search".toUri()
+ "http://localhost:${searchMockServer.port}/pages/searchResults.html?search=firefox".toUri()
val searchEngineName = "TestSearchEngine"
// setting our custom mockWebServer search URL
setCustomSearchEngine(searchMockServer, searchEngineName)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt
index be99ebe8af..224de9a675 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt
@@ -5,7 +5,6 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
@@ -47,7 +46,6 @@ class CrashReportingTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2336134
- @Ignore("Test failure caused by: https://github.com/mozilla-mobile/fenix/issues/19964")
@Test
fun restoreTabFromTabCrashedReporterTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt
index 2e881e16fe..938c13d857 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt
@@ -51,7 +51,7 @@ class FirefoxSuggestTest : TestSetup() {
),
"Houzz" to listOf(
"Houzz.com - Official Site",
- "houzz.com/products?m_refid=us-dsp-mpl-admp-219577_15416306_kwd-353208810&adcid=319104989&mfadid=adm&utm_source=admarketplace&utm_medium=cpc&utm_campaign=Privacy&utm_term=houzz&utm_content=319104989us1287${getSponsoredFxSuggestPlaceHolder()}",
+ "houzz.com/products?m_refid=us-dsp-mpl-admp-219577_15416306_kwd-353208810&adcid=319104989us1287${getSponsoredFxSuggestPlaceHolder()}&utm_source=admarketplace&utm_medium=cpc&utm_campaign=Privacy&utm_term=houzz&utm_content=319104989&mfadid=adm",
),
"Spanx" to listOf(
"SPANX® - Official Site",
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt
index 317aa9c397..b551ec831a 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt
@@ -8,7 +8,6 @@ import android.os.Build
import android.view.autofill.AutofillManager
import androidx.core.net.toUri
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
@@ -538,7 +537,6 @@ class LoginsTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/593768
- @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1812995")
@Test
fun doNotSaveOptionWillNotUpdateALoginTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html"
@@ -547,19 +545,18 @@ class LoginsTest : TestSetup() {
navigationToolbar {
}.enterURLAndEnterToBrowser(loginPage.toUri()) {
setPageObjectText(itemWithResId("username"), "mozilla")
+ waitForAppWindowToBeUpdated()
setPageObjectText(itemWithResId("password"), "firefox")
+ waitForAppWindowToBeUpdated()
clickPageObject(itemWithResId("submit"))
verifySaveLoginPromptIsDisplayed()
clickPageObject(itemWithText("Save"))
- }.openTabDrawer {
- closeTab()
- }
-
- navigationToolbar {
- }.enterURLAndEnterToBrowser(loginPage.toUri()) {
+ waitForAppWindowToBeUpdated()
clickPageObject(itemWithResId("togglePassword"))
setPageObjectText(itemWithResId("username"), "mozilla")
+ waitForAppWindowToBeUpdated()
setPageObjectText(itemWithResId("password"), "fenix")
+ waitForAppWindowToBeUpdated()
clickPageObject(itemWithResId("submit"))
verifySaveLoginPromptIsDisplayed()
clickPageObject(itemWithText("Don’t update"))
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
index 95ced206a2..cad28b1878 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
@@ -84,7 +84,7 @@ class NimbusMessagingHomescreenTest : TestSetup() {
HomeScreenSection.POCKET to false,
HomeScreenSection.POCKET_SPONSORED_STORIES to false,
HomeScreenSection.RECENT_EXPLORATIONS to false,
- HomeScreenSection.RECENTLY_SAVED to false,
+ HomeScreenSection.BOOKMARKS to false,
HomeScreenSection.TOP_SITES to false,
),
)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt
index 4eead4f63c..d2da41ca11 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt
@@ -1,9 +1,12 @@
package org.mozilla.fenix.ui
+import android.os.Build
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
+import org.mozilla.fenix.helpers.AppAndSystemHelper.dismissSetAsDefaultBrowserOnboardingDialog
+import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithLauncherIntent
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestSetup
@@ -20,9 +23,13 @@ class OnboardingTest : TestSetup() {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2122321
@Test
fun verifyFirstOnboardingCardItemsTest() {
- runWithLauncherIntent(activityTestRule) {
- homeScreen {
- verifyFirstOnboardingCard(activityTestRule)
+ // Run UI test only on devices with Android version lower than 10
+ // because on Android 10 and above, the default browser dialog is shown and the first onboarding card is skipped
+ runWithCondition(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ runWithLauncherIntent(activityTestRule) {
+ homeScreen {
+ verifyFirstOnboardingCard(activityTestRule)
+ }
}
}
}
@@ -31,15 +38,19 @@ class OnboardingTest : TestSetup() {
@SmokeTest
@Test
fun verifyFirstOnboardingCardItemsFunctionalityTest() {
- runWithLauncherIntent(activityTestRule) {
- homeScreen {
- clickDefaultCardNotNowOnboardingButton(activityTestRule)
- verifySecondOnboardingCard(activityTestRule)
- swipeSecondOnboardingCardToRight()
- }.clickSetAsDefaultBrowserOnboardingButton(activityTestRule) {
- verifyAndroidDefaultAppsMenuAppears()
- }.goBackToOnboardingScreen {
- verifySecondOnboardingCard(activityTestRule)
+ // Run UI test only on devices with Android version lower than 10
+ // because on Android 10 and above, the default browser dialog is shown and the first onboarding card is skipped
+ runWithCondition(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ runWithLauncherIntent(activityTestRule) {
+ homeScreen {
+ clickDefaultCardNotNowOnboardingButton(activityTestRule)
+ verifySecondOnboardingCard(activityTestRule)
+ swipeSecondOnboardingCardToRight()
+ }.clickSetAsDefaultBrowserOnboardingButton(activityTestRule) {
+ verifyAndroidDefaultAppsMenuAppears()
+ }.goBackToOnboardingScreen {
+ verifySecondOnboardingCard(activityTestRule)
+ }
}
}
}
@@ -49,7 +60,12 @@ class OnboardingTest : TestSetup() {
fun verifySecondOnboardingCardItemsTest() {
runWithLauncherIntent(activityTestRule) {
homeScreen {
- clickDefaultCardNotNowOnboardingButton(activityTestRule)
+ // Check if the device is running on Android version lower than 10
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ // If true, click the "Not Now" button from the first onboarding card
+ clickDefaultCardNotNowOnboardingButton(activityTestRule)
+ }
+ dismissSetAsDefaultBrowserOnboardingDialog()
verifySecondOnboardingCard(activityTestRule)
}
}
@@ -61,7 +77,12 @@ class OnboardingTest : TestSetup() {
fun verifyThirdOnboardingCardSignInFunctionalityTest() {
runWithLauncherIntent(activityTestRule) {
homeScreen {
- clickDefaultCardNotNowOnboardingButton(activityTestRule)
+ // Check if the device is running on Android version lower than 10
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ // If true, click the "Not Now" button from the first onboarding card
+ clickDefaultCardNotNowOnboardingButton(activityTestRule)
+ }
+ dismissSetAsDefaultBrowserOnboardingDialog()
verifySecondOnboardingCard(activityTestRule)
clickAddSearchWidgetNotNowOnboardingButton(activityTestRule)
verifyThirdOnboardingCard(activityTestRule)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt
index 674924c954..e5d52152e3 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt
@@ -2,6 +2,7 @@ package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.Constants
@@ -63,6 +64,7 @@ class PocketTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2252513
+ @Ignore("Bug 1868291 - Intermittent failure in org.mozilla.fenix.ui.PocketTest.openPocketStoryItemTest")
@Test
fun openPocketStoryItemTest() {
activityTestRule.activityRule.applySettingsExceptions {
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt
index ede7b06b5d..6d2202c3ba 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt
@@ -68,7 +68,7 @@ class SearchTest : TestSetup() {
private lateinit var searchMockServer: MockWebServer
private var queryString = "firefox"
private val generalEnginesList = listOf("DuckDuckGo", "Google", "Bing")
- private val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
+ private val topicEnginesList = listOf("Wikipedia", "eBay")
@get:Rule
val activityTestRule = AndroidComposeTestRule(
@@ -123,7 +123,7 @@ class SearchTest : TestSetup() {
verifySearchToolbar(isDisplayed = true)
clickSearchSelectorButton()
verifySearchShortcutListContains(
- "DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay",
+ "DuckDuckGo", "Google", "Wikipedia", "Bing", "eBay",
"Bookmarks", "Tabs", "History", "Search settings",
)
}
@@ -165,7 +165,7 @@ class SearchTest : TestSetup() {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154196
@Test
fun verifySearchPlaceholderForTopicSpecificSearchEnginesTest() {
- val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
+ val topicEnginesList = listOf("Wikipedia", "eBay")
topicEnginesList.forEach {
homeScreen {
@@ -241,7 +241,7 @@ class SearchTest : TestSetup() {
@SmokeTest
@Test
fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() {
- val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay")
+ val enginesList = listOf("DuckDuckGo", "Google", "Wikipedia", "Bing", "eBay")
enginesList.forEach {
homeScreen {
@@ -802,7 +802,6 @@ class SearchTest : TestSetup() {
verifySearchShortcutListContains(
"Google",
"Bing",
- "Amazon.com",
"DuckDuckGo",
"ويكيبيديا (ar)",
)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt
index 3e37fb5e3b..1144deb9c1 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt
@@ -21,7 +21,7 @@ import org.mozilla.fenix.ui.robots.homeScreen
class SettingsAboutTest : TestSetup() {
@get:Rule
- val activityIntentTestRule = HomeActivityIntentTestRule()
+ val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
@Rule
@JvmField
@@ -61,10 +61,6 @@ class SettingsAboutTest : TestSetup() {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246961
@Test
fun verifyAboutFirefoxMenuItems() {
- activityIntentTestRule.applySettingsExceptions {
- it.isJumpBackInCFREnabled = false
- it.isTCPCFREnabled = false
- }
homeScreen {
}.openThreeDotMenu {
}.openSettings {
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt
index 8dc31c64e8..0f41e4ac94 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt
@@ -124,12 +124,12 @@ class SettingsHomepageTest : TestSetup() {
}.openThreeDotMenu {
}.bookmarkPage {
}.goToHomescreen {
- verifyRecentBookmarksSectionIsDisplayed(exists = true)
+ verifyBookmarksSectionIsDisplayed(exists = true)
}.openThreeDotMenu {
}.openCustomizeHome {
clickRecentBookmarksButton()
}.goBackToHomeScreen {
- verifyRecentBookmarksSectionIsDisplayed(exists = false)
+ verifyBookmarksSectionIsDisplayed(exists = false)
}
}
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt
index 5abbaa8b4a..d12d3a9c8c 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt
@@ -9,7 +9,6 @@ import androidx.test.espresso.Espresso.pressBack
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
@@ -511,7 +510,6 @@ class SettingsSearchTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/412927
- @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test
fun verifyShowClipboardSuggestionsToggleTest() {
val link = "https://www.mozilla.org/en-US/"
@@ -599,12 +597,11 @@ class SettingsSearchTest : TestSetup() {
verifySearchShortcutChecked(
EngineShortcut(name = "Google", checkboxIndex = 1, isChecked = true),
EngineShortcut(name = "Bing", checkboxIndex = 4, isChecked = true),
- EngineShortcut(name = "Amazon.com", checkboxIndex = 7, isChecked = true),
- EngineShortcut(name = "DuckDuckGo", checkboxIndex = 10, isChecked = true),
- EngineShortcut(name = "eBay", checkboxIndex = 13, isChecked = true),
- EngineShortcut(name = "Wikipedia", checkboxIndex = 16, isChecked = true),
- EngineShortcut(name = "Reddit", checkboxIndex = 19, isChecked = false),
- EngineShortcut(name = "YouTube", checkboxIndex = 22, isChecked = false),
+ EngineShortcut(name = "DuckDuckGo", checkboxIndex = 7, isChecked = true),
+ EngineShortcut(name = "eBay", checkboxIndex = 10, isChecked = true),
+ EngineShortcut(name = "Wikipedia", checkboxIndex = 13, isChecked = true),
+ EngineShortcut(name = "Reddit", checkboxIndex = 16, isChecked = false),
+ EngineShortcut(name = "YouTube", checkboxIndex = 19, isChecked = false),
)
}
}
@@ -619,14 +616,13 @@ class SettingsSearchTest : TestSetup() {
}.openSearchSubMenu {
openManageShortcutsMenu()
selectSearchShortcut(EngineShortcut(name = "Google", checkboxIndex = 1))
- selectSearchShortcut(EngineShortcut(name = "Amazon.com", checkboxIndex = 7))
- selectSearchShortcut(EngineShortcut(name = "Reddit", checkboxIndex = 19))
- selectSearchShortcut(EngineShortcut(name = "YouTube", checkboxIndex = 22))
+ selectSearchShortcut(EngineShortcut(name = "Reddit", checkboxIndex = 16))
+ selectSearchShortcut(EngineShortcut(name = "YouTube", checkboxIndex = 19))
exitMenu()
}
searchScreen {
clickSearchSelectorButton()
- verifySearchShortcutListContains("Google", "Amazon.com", shouldExist = false)
+ verifySearchShortcutListContains("Google", shouldExist = false)
verifySearchShortcutListContains("YouTube", shouldExist = true)
verifySearchShortcutListContains("Reddit", shouldExist = true)
}
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt
index 4b3842fc6a..720f90c4c8 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt
@@ -8,7 +8,6 @@ import androidx.core.net.toUri
import androidx.test.espresso.Espresso.pressBack
import androidx.test.filters.SdkSuppress
import mozilla.components.concept.engine.mediasession.MediaSession
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
@@ -146,7 +145,6 @@ class SettingsSitePermissionsTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2286807
- @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1827599")
@SmokeTest
@Test
fun verifyAutoplayBlockAudioOnlySettingOnMutedVideoTest() {
@@ -210,7 +208,6 @@ class SettingsSitePermissionsTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2286806
- @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1827599")
@Test
fun verifyAutoplayAllowAudioVideoSettingOnMutedVideoTest() {
val mutedVideoTestPage = getMutedVideoPageAsset(mockWebServer)
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt
index 2732ccbcab..cbbceaff97 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt
@@ -430,8 +430,8 @@ class HomeScreenRobot {
fun verifyJumpBackInShowAllButton() = assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_show_all)))
fun verifyRecentlyVisitedSectionIsDisplayed(exists: Boolean) =
assertUIObjectExists(itemContainingText(getStringResource(R.string.history_metadata_header_2)), exists = exists)
- fun verifyRecentBookmarksSectionIsDisplayed(exists: Boolean) =
- assertUIObjectExists(itemContainingText(getStringResource(R.string.recently_saved_title)), exists = exists)
+ fun verifyBookmarksSectionIsDisplayed(exists: Boolean) =
+ assertUIObjectExists(itemContainingText(getStringResource(R.string.home_bookmarks_title)), exists = exists)
fun verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) {
// checks if the search group exists in the Recently visited section
@@ -439,12 +439,12 @@ class HomeScreenRobot {
scrollToElementByText("Recently visited")
assertUIObjectExists(
itemContainingText(searchTerm)
- .getFromParent(UiSelector().text("$groupSize sites")),
+ .getFromParent(UiSelector().text("$groupSize pages")),
)
} else {
assertUIObjectIsGone(
itemContainingText(searchTerm)
- .getFromParent(UiSelector().text("$groupSize sites")),
+ .getFromParent(UiSelector().text("$groupSize pages")),
)
}
}
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt
index 9d1c919a37..c78994784a 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt
@@ -444,7 +444,7 @@ private fun jumpBackInButton() =
onView(allOf(withText(R.string.customize_toggle_jump_back_in)))
private fun recentBookmarksButton() =
- onView(allOf(withText(R.string.customize_toggle_recent_bookmarks)))
+ onView(allOf(withText(R.string.customize_toggle_bookmarks)))
private fun recentlyVisitedButton() =
onView(allOf(withText(R.string.customize_toggle_recently_visited)))
diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt
index a20a79088a..70317c8937 100644
--- a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt
+++ b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt
@@ -162,23 +162,25 @@ class ThreeDotMenuMainRobot {
assertUIObjectExists(
normalBrowsingNewTabButton(),
bookmarksButton(),
+ addBookmarkButton(),
historyButton(),
downloadsButton(),
+ passwordsButton(),
addOnsButton(),
syncAndSaveDataButton(),
findInPageButton(),
+ translateButton(),
desktopSiteButton(),
reportSiteIssueButton(),
- addToHomeScreenButton(),
- addToShortcutsButton(),
- saveToCollectionButton(),
- addBookmarkButton(),
desktopSiteToggle(isRequestDesktopSiteEnabled),
- translateButton(),
+
)
// Swipe to second part of menu
expandMenu()
assertUIObjectExists(
+ addToHomeScreenButton(),
+ addToShortcutsButton(),
+ saveToCollectionButton(),
settingsButton(),
)
if (FxNimbus.features.print.value().browserPrintEnabled) {
@@ -197,6 +199,7 @@ class ThreeDotMenuMainRobot {
bookmarksButton(),
historyButton(),
downloadsButton(),
+ passwordsButton(),
addOnsButton(),
// Disabled step due to https://github.com/mozilla-mobile/fenix/issues/26788
// syncAndSaveDataButton,
@@ -717,6 +720,8 @@ private fun historyButton() =
itemContainingText(getStringResource(R.string.library_history))
private fun downloadsButton() =
itemContainingText(getStringResource(R.string.library_downloads))
+private fun passwordsButton() =
+ itemContainingText(getStringResource(R.string.browser_menu_passwords))
private fun addOnsButton() =
itemContainingText(getStringResource(R.string.browser_menu_extensions))
private fun desktopSiteButton() =
diff --git a/mobile/android/fenix/app/src/beta/res/xml/shortcuts.xml b/mobile/android/fenix/app/src/beta/res/xml/shortcuts.xml
index dcf89bab7b..2da32f3afe 100644
--- a/mobile/android/fenix/app/src/beta/res/xml/shortcuts.xml
+++ b/mobile/android/fenix/app/src/beta/res/xml/shortcuts.xml
@@ -8,8 +8,7 @@
android:shortcutId="password_manager"
android:enabled="true"
android:icon="@drawable/ic_static_password_shortcut"
- android:shortcutShortLabel="@string/home_screen_shortcut_passwords"
- android:shortcutLongLabel="@string/home_screen_shortcut_passwords">
+ android:shortcutShortLabel="@string/home_screen_shortcut_passwords">
+ android:shortcutShortLabel="@string/home_screen_shortcut_open_new_tab_2">
+ android:shortcutShortLabel="@string/home_screen_shortcut_open_new_private_tab_2">
+ android:shortcutShortLabel="@string/home_screen_shortcut_passwords">
+ android:shortcutShortLabel="@string/home_screen_shortcut_open_new_tab_2">
+ android:shortcutShortLabel="@string/home_screen_shortcut_open_new_private_tab_2">
window.history.back() );
- }
+document.addEventListener("DOMContentLoaded", function () {
+ if (window.history.length == 1) {
+ document.getElementById("backButton").style.display = "none";
+ } else {
+ document
+ .getElementById("backButton")
+ .addEventListener("click", () => window.history.back());
+ }
});
parseQuery(document.documentURI);
diff --git a/mobile/android/fenix/app/src/main/assets/high_risk_error_pages.html b/mobile/android/fenix/app/src/main/assets/high_risk_error_pages.html
index c73012b143..7f0e6e3fc6 100644
--- a/mobile/android/fenix/app/src/main/assets/high_risk_error_pages.html
+++ b/mobile/android/fenix/app/src/main/assets/high_risk_error_pages.html
@@ -8,7 +8,10 @@
-
+
diff --git a/mobile/android/fenix/app/src/main/assets/lowMediumErrorPages.js b/mobile/android/fenix/app/src/main/assets/lowMediumErrorPages.js
index 760ce65868..23a3fe91b4 100644
--- a/mobile/android/fenix/app/src/main/assets/lowMediumErrorPages.js
+++ b/mobile/android/fenix/app/src/main/assets/lowMediumErrorPages.js
@@ -6,52 +6,56 @@
* Handles the parsing of the ErrorPages URI and then passes them to injectValues
*/
function parseQuery(queryString) {
- if (queryString[0] === '?') {
- queryString = queryString.substr(1);
- }
- const query = Object.fromEntries(new URLSearchParams(queryString).entries());
- injectValues(query);
- updateShowSSL(query);
- updateShowHSTS(query);
-};
+ if (queryString[0] === "?") {
+ queryString = queryString.substr(1);
+ }
+ const query = Object.fromEntries(new URLSearchParams(queryString).entries());
+ injectValues(query);
+ updateShowSSL(query);
+ updateShowHSTS(query);
+}
/**
* Updates the HTML elements based on the queryMap
*/
function injectValues(queryMap) {
- const tryAgainButton = document.getElementById('errorTryAgain');
- const continueHttpButton = document.getElementById("continueHttp");
- const backFromHttpButton = document.getElementById('backFromHttp');
+ const tryAgainButton = document.getElementById("errorTryAgain");
+ const continueHttpButton = document.getElementById("continueHttp");
+ const backFromHttpButton = document.getElementById("backFromHttp");
- // Go through each element and inject the values
- document.title = queryMap.title;
- tryAgainButton.innerHTML = queryMap.button;
- continueHttpButton.innerHTML = queryMap.continueHttpButton;
- backFromHttpButton.innerHTML = queryMap.badCertGoBack;
- document.getElementById('errorTitleText').innerHTML = queryMap.title;
- document.getElementById('errorShortDesc').innerHTML = queryMap.description;
- document.getElementById('advancedButton').innerHTML = queryMap.badCertAdvanced;
- document.getElementById('badCertTechnicalInfo').innerHTML = queryMap.badCertTechInfo;
- document.getElementById('advancedPanelBackButton').innerHTML = queryMap.badCertGoBack;
- document.getElementById('advancedPanelAcceptButton').innerHTML = queryMap.badCertAcceptTemporary;
+ // Go through each element and inject the values
+ document.title = queryMap.title;
+ tryAgainButton.innerHTML = queryMap.button;
+ continueHttpButton.innerHTML = queryMap.continueHttpButton;
+ backFromHttpButton.innerHTML = queryMap.badCertGoBack;
+ document.getElementById("errorTitleText").innerHTML = queryMap.title;
+ document.getElementById("errorShortDesc").innerHTML = queryMap.description;
+ document.getElementById("advancedButton").innerHTML =
+ queryMap.badCertAdvanced;
+ document.getElementById("badCertTechnicalInfo").innerHTML =
+ queryMap.badCertTechInfo;
+ document.getElementById("advancedPanelBackButton").innerHTML =
+ queryMap.badCertGoBack;
+ document.getElementById("advancedPanelAcceptButton").innerHTML =
+ queryMap.badCertAcceptTemporary;
- // If no image is passed in, remove the element so as not to leave an empty iframe
- const errorImage = document.getElementById('errorImage');
- if (!queryMap.image) {
- errorImage.remove();
- } else {
- errorImage.src = "resource://android/assets/" + queryMap.image;
- }
+ // If no image is passed in, remove the element so as not to leave an empty iframe
+ const errorImage = document.getElementById("errorImage");
+ if (!queryMap.image) {
+ errorImage.remove();
+ } else {
+ errorImage.src = "resource://android/assets/" + queryMap.image;
+ }
- if (queryMap.showContinueHttp === "true") {
- // On the "HTTPS-Only" error page "Try again" doesn't make sense since reloading the page
- // will just show an error page again.
- tryAgainButton.style.display = 'none';
- } else {
- continueHttpButton.style.display = 'none';
- backFromHttpButton.style.display = 'none';
- }
-};
+ if (queryMap.showContinueHttp === "true") {
+ // On the "HTTPS-Only" error page "Try again" doesn't make sense since reloading the page
+ // will just show an error page again.
+ tryAgainButton.style.display = "none";
+ } else {
+ continueHttpButton.style.display = "none";
+ backFromHttpButton.style.display = "none";
+ }
+}
let advancedVisible = false;
@@ -59,88 +63,98 @@ let advancedVisible = false;
* Used to show or hide the "accept" button based on the validity of the SSL certificate
*/
function updateShowSSL(queryMap) {
- /** @type {'true' | 'false'} */
- const showSSL = queryMap.showSSL;
- if (typeof document.addCertException === 'undefined') {
- document.getElementById('advancedButton').style.display='none';
+ /** @type {'true' | 'false'} */
+ const showSSL = queryMap.showSSL;
+ if (typeof document.addCertException === "undefined") {
+ document.getElementById("advancedButton").style.display = "none";
+ } else {
+ if (showSSL === "true") {
+ document.getElementById("advancedButton").style.display = "block";
} else {
- if (showSSL === 'true') {
- document.getElementById('advancedButton').style.display='block';
- } else {
- document.getElementById('advancedButton').style.display='none';
- }
+ document.getElementById("advancedButton").style.display = "none";
}
-};
+ }
+}
/**
* Used to show or hide the "accept" button based for the HSTS error page
*/
function updateShowHSTS(queryMap) {
- const showHSTS = queryMap.showHSTS;
- if (showHSTS === 'true') {
- document.getElementById('advancedButton').style.display='block';
- document.getElementById('advancedPanelAcceptButton').style.display='none';
- }
-};
+ const showHSTS = queryMap.showHSTS;
+ if (showHSTS === "true") {
+ document.getElementById("advancedButton").style.display = "block";
+ document.getElementById("advancedPanelAcceptButton").style.display = "none";
+ }
+}
/**
* Used to display information about the SSL certificate in `error_pages.html`
*/
function toggleAdvancedAndScroll() {
- const advancedPanel = document.getElementById('badCertAdvancedPanel');
- if (advancedVisible) {
- advancedPanel.style.display='none';
- } else {
- advancedPanel.style.display='block';
- }
- advancedVisible = !advancedVisible;
+ const advancedPanel = document.getElementById("badCertAdvancedPanel");
+ if (advancedVisible) {
+ advancedPanel.style.display = "none";
+ } else {
+ advancedPanel.style.display = "block";
+ }
+ advancedVisible = !advancedVisible;
- const horizontalLine = document.getElementById("horizontalLine");
- const advancedPanelAcceptButton = document.getElementById(
- "advancedPanelAcceptButton"
- );
- const badCertAdvancedPanel = document.getElementById(
- "badCertAdvancedPanel"
- );
+ const horizontalLine = document.getElementById("horizontalLine");
+ const advancedPanelAcceptButton = document.getElementById(
+ "advancedPanelAcceptButton"
+ );
+ const badCertAdvancedPanel = document.getElementById("badCertAdvancedPanel");
- // We know that the button is being displayed
- if (badCertAdvancedPanel.style.display === "block") {
- horizontalLine.hidden = false;
- advancedPanelAcceptButton.scrollIntoView({
- behavior: "smooth",
- block: "center",
- inline: "nearest",
- });
- } else {
- horizontalLine.hidden = true;
- }
-};
+ // We know that the button is being displayed
+ if (badCertAdvancedPanel.style.display === "block") {
+ horizontalLine.hidden = false;
+ advancedPanelAcceptButton.scrollIntoView({
+ behavior: "smooth",
+ block: "center",
+ inline: "nearest",
+ });
+ } else {
+ horizontalLine.hidden = true;
+ }
+}
/**
* Used to bypass an SSL pages in `error_pages.html`
*/
async function acceptAndContinue(temporary) {
- try {
- await document.addCertException(temporary);
- location.reload();
- } catch (error) {
- console.error("Unexpected error: " + error);
- }
-};
+ try {
+ await document.addCertException(temporary);
+ location.reload();
+ } catch (error) {
+ console.error("Unexpected error: " + error);
+ }
+}
-document.addEventListener('DOMContentLoaded', function () {
- if (window.history.length == 1) {
- document.getElementById('advancedPanelBackButton').style.display = 'none';
- document.getElementById('backFromHttp').style.display = 'none';
- } else {
- document.getElementById('advancedPanelBackButton').addEventListener('click', () => window.history.back());
- document.getElementById('backFromHttp').addEventListener('click', () => window.history.back());
- }
+document.addEventListener("DOMContentLoaded", function () {
+ if (window.history.length == 1) {
+ document.getElementById("advancedPanelBackButton").style.display = "none";
+ document.getElementById("backFromHttp").style.display = "none";
+ } else {
+ document
+ .getElementById("advancedPanelBackButton")
+ .addEventListener("click", () => window.history.back());
+ document
+ .getElementById("backFromHttp")
+ .addEventListener("click", () => window.history.back());
+ }
- document.getElementById('errorTryAgain').addEventListener('click', () => window.location.reload());
- document.getElementById('advancedButton').addEventListener('click', toggleAdvancedAndScroll);
- document.getElementById('advancedPanelAcceptButton').addEventListener('click', () => acceptAndContinue(true));
- document.getElementById('continueHttp').addEventListener('click', () => document.reloadWithHttpsOnlyException());
+ document
+ .getElementById("errorTryAgain")
+ .addEventListener("click", () => window.location.reload());
+ document
+ .getElementById("advancedButton")
+ .addEventListener("click", toggleAdvancedAndScroll);
+ document
+ .getElementById("advancedPanelAcceptButton")
+ .addEventListener("click", () => acceptAndContinue(true));
+ document
+ .getElementById("continueHttp")
+ .addEventListener("click", () => document.reloadWithHttpsOnlyException());
});
parseQuery(document.documentURI);
diff --git a/mobile/android/fenix/app/src/main/assets/low_and_medium_risk_error_pages.html b/mobile/android/fenix/app/src/main/assets/low_and_medium_risk_error_pages.html
index 62e0c70988..84d8800ea5 100644
--- a/mobile/android/fenix/app/src/main/assets/low_and_medium_risk_error_pages.html
+++ b/mobile/android/fenix/app/src/main/assets/low_and_medium_risk_error_pages.html
@@ -8,7 +8,10 @@
-
+
-
+
@@ -56,9 +56,7 @@
id="advancedPanelBackButtonContainer"
class="advancedPanelButtonContainer"
>
-
+
if (window.history.length == 1) {
- document.getElementById('advancedPanelBackButton').style.display = 'none';
+ document.getElementById("advancedPanelBackButton").style.display = "none";
}
function toggleAdvancedAndScroll() {
@@ -104,5 +102,5 @@
}
-
+
diff --git a/mobile/android/fenix/app/src/main/assets/shared_error_style.css b/mobile/android/fenix/app/src/main/assets/shared_error_style.css
index 5753b00a78..fc6a109003 100644
--- a/mobile/android/fenix/app/src/main/assets/shared_error_style.css
+++ b/mobile/android/fenix/app/src/main/assets/shared_error_style.css
@@ -48,7 +48,6 @@ li:not(:last-of-type) {
}
h1 {
- margin: 0;
padding: 0;
margin: var(--moz-vertical-spacing) 0;
color: var(--header-color);
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt
index aa8a5250a7..4d4ce12330 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt
@@ -50,7 +50,7 @@ object FeatureFlags {
/**
* Enables compose on the tabs tray items.
*/
- val composeTabsTray = Config.channel.isNightlyOrDebug || Config.channel.isBeta
+ const val composeTabsTray = true
/**
* Enables compose on the top sites.
@@ -87,4 +87,9 @@ object FeatureFlags {
* Enables the menu redesign.
*/
const val menuRedesignEnabled = false
+
+ /**
+ * Enables microsurveys.
+ */
+ const val microsurveysEnabled = false
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
index 7c32c02f60..cd367fa467 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
@@ -206,10 +206,11 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
lazy(LazyThreadSafetyMode.NONE) { components.core.client },
),
enableEventTimestamps = FxNimbus.features.glean.value().enableEventTimestamps,
+ delayPingLifetimeIo = FxNimbus.features.glean.value().delayPingLifetimeIo,
)
// Set the metric configuration from Nimbus.
- Glean.setMetricsEnabledConfig(FxNimbus.features.glean.value().metricsEnabled)
+ Glean.applyServerKnobsConfig(FxNimbus.features.glean.value().metricsEnabled)
Glean.initialize(
applicationContext = this,
@@ -870,7 +871,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
disabledAds.set(!settings.isReviewQualityCheckProductRecommendationsEnabled)
}
- TabStrip.enabled.set(settings.isTabletAndTabStripEnabled)
+ TabStrip.enabled.set(settings.isTabStripEnabled)
}
@VisibleForTesting
@@ -991,7 +992,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
// We break them out here so they can be recorded when
// `nimbus.applyPendingExperiments()` is called.
CustomizeHome.jumpBackIn.set(settings.showRecentTabsFeature)
- CustomizeHome.recentlySaved.set(settings.showRecentBookmarksFeature)
+ CustomizeHome.bookmarks.set(settings.showBookmarksHomeFeature)
CustomizeHome.mostVisitedSites.set(settings.showTopSitesFeature)
CustomizeHome.recentlyVisited.set(settings.historyMetadataUIFeature)
CustomizeHome.pocket.set(settings.showPocketRecommendationsFeature)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
index 1b17a97507..bf442fab37 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
@@ -115,6 +115,7 @@ import org.mozilla.fenix.home.intent.CrashReporterIntentProcessor
import org.mozilla.fenix.home.intent.HomeDeepLinkIntentProcessor
import org.mozilla.fenix.home.intent.OpenBrowserIntentProcessor
import org.mozilla.fenix.home.intent.OpenPasswordManagerIntentProcessor
+import org.mozilla.fenix.home.intent.OpenRecentlyClosedIntentProcessor
import org.mozilla.fenix.home.intent.OpenSpecificTabIntentProcessor
import org.mozilla.fenix.home.intent.ReEngagementIntentProcessor
import org.mozilla.fenix.home.intent.SpeechProcessingIntentProcessor
@@ -203,6 +204,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
OpenBrowserIntentProcessor(this, ::getIntentSessionId),
OpenSpecificTabIntentProcessor(this),
OpenPasswordManagerIntentProcessor(),
+ OpenRecentlyClosedIntentProcessor(),
ReEngagementIntentProcessor(this, settings()),
)
}
@@ -780,7 +782,16 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
private fun handleBackLongPress(): Boolean {
supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach {
- if (it is OnBackLongPressedListener && it.onBackLongPressed()) {
+ if (it is OnLongPressedListener && it.onBackLongPressed()) {
+ return true
+ }
+ }
+ return false
+ }
+
+ private fun handleForwardLongPress(): Boolean {
+ supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach {
+ if (it is OnLongPressedListener && it.onForwardLongPressed()) {
return true
}
}
@@ -805,9 +816,16 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
handleBackLongPress()
}
}
+
+ if (keyCode == KeyEvent.KEYCODE_FORWARD) {
+ event?.startTracking()
+ return true
+ }
+
return super.onKeyDown(keyCode, event)
}
+ @Suppress("ReturnCount")
final override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
if (shouldUseCustomBackLongPress() && keyCode == KeyEvent.KEYCODE_BACK) {
backLongPressJob?.cancel()
@@ -821,6 +839,20 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
return true
}
}
+
+ if (keyCode == KeyEvent.KEYCODE_FORWARD) {
+ if (navHost.navController.hasTopDestination(TabHistoryDialogFragment.NAME)) {
+ // returning true avoids further processing of the KeyUp event
+ return true
+ }
+
+ supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach {
+ if (it is UserInteractionHandler && it.onForwardPressed()) {
+ return true
+ }
+ }
+ }
+
return super.onKeyUp(keyCode, event)
}
@@ -830,6 +862,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
if (!shouldUseCustomBackLongPress() && keyCode == KeyEvent.KEYCODE_BACK) {
return handleBackLongPress()
}
+
+ if (keyCode == KeyEvent.KEYCODE_FORWARD) {
+ return handleForwardLongPress()
+ }
+
return super.onKeyLongPress(keyCode, event)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/OnBackLongPressedListener.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/OnBackLongPressedListener.kt
deleted file mode 100644
index e47a0b71b4..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/OnBackLongPressedListener.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix
-
-/**
- * Interface for features and fragments that want to handle long presses of the system back button
- */
-interface OnBackLongPressedListener {
-
- /**
- * Called when the system back button is long pressed.
- *
- * Note: This cannot be called when gesture navigation is enabled on Android 10+ due to system
- * limitations.
- *
- * @return true if the event was handled
- */
- fun onBackLongPressed(): Boolean
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/OnLongPressedListener.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/OnLongPressedListener.kt
new file mode 100644
index 0000000000..711830bf72
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/OnLongPressedListener.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
+
+/**
+ * Interface for features and fragments that want to handle long presses of the system back/forward button
+ */
+interface OnLongPressedListener {
+
+ /**
+ * Called when the system back button is long pressed.
+ *
+ * Note: This cannot be called when gesture navigation is enabled on Android 10+ due to system
+ * limitations.
+ *
+ * @return true if the event was handled
+ */
+ fun onBackLongPressed(): Boolean
+
+ /**
+ * Called when the system forward button is long pressed.
+ *
+ * @return true if the event was handled
+ */
+ fun onForwardLongPressed(): Boolean
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
index 5eeeeedb3e..0198cb9653 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
@@ -40,6 +40,7 @@ import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.settings.SupportUtils
+import org.mozilla.fenix.settings.SupportUtils.AMO_HOMEPAGE_FOR_ANDROID
import org.mozilla.fenix.theme.ThemeManager
/**
@@ -264,11 +265,4 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
from = BrowserDirection.FromAddonsManagementFragment,
)
}
-
- companion object {
- // This is locale-less on purpose so that the content negotiation happens on the AMO side because the current
- // user language might not be supported by AMO and/or the language might not be exactly what AMO is expecting
- // (e.g. `en` instead of `en-US`).
- private const val AMO_HOMEPAGE_FOR_ANDROID = "${BuildConfig.AMO_BASE_URL}/android/"
- }
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
index d6e93e0043..2567021e7e 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
@@ -115,25 +115,29 @@ import mozilla.components.support.ktx.android.view.hideKeyboard
import mozilla.components.support.ktx.kotlin.getOrigin
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import mozilla.components.support.locale.ActivityContextWrapper
+import mozilla.components.support.utils.ext.isLandscape
import mozilla.components.ui.widgets.withCenterAlignedButtons
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.GleanMetrics.Events
+import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.GleanMetrics.MediaState
import org.mozilla.fenix.GleanMetrics.NavigationBar
import org.mozilla.fenix.GleanMetrics.PullToRefreshInBrowser
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.IntentReceiverActivity
import org.mozilla.fenix.NavGraphDirections
-import org.mozilla.fenix.OnBackLongPressedListener
+import org.mozilla.fenix.OnLongPressedListener
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.readermode.DefaultReaderModeController
import org.mozilla.fenix.browser.tabstrip.TabStrip
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.FindInPageIntegration
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.appstate.AppAction
+import org.mozilla.fenix.components.menu.MenuAccessPoint
import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.components.toolbar.BrowserFragmentState
import org.mozilla.fenix.components.toolbar.BrowserFragmentStore
@@ -165,6 +169,7 @@ import org.mozilla.fenix.ext.breadcrumb
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.hideToolbar
+import org.mozilla.fenix.ext.isTablet
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.navigateWithBreadcrumb
import org.mozilla.fenix.ext.registerForActivityResult
@@ -173,6 +178,7 @@ import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.secure
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.tabClosedUndoMessage
+import org.mozilla.fenix.ext.updateNavBarForConfigurationChange
import org.mozilla.fenix.home.HomeScreenViewModel
import org.mozilla.fenix.home.SharedViewModel
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
@@ -201,7 +207,7 @@ abstract class BaseBrowserFragment :
Fragment(),
UserInteractionHandler,
ActivityResultHandler,
- OnBackLongPressedListener,
+ OnLongPressedListener,
AccessibilityManager.AccessibilityStateChangeListener {
private var _binding: FragmentBrowserBinding? = null
@@ -212,7 +218,9 @@ abstract class BaseBrowserFragment :
private lateinit var startForResult: ActivityResultLauncher
private var _browserToolbarInteractor: BrowserToolbarInteractor? = null
- protected val browserToolbarInteractor: BrowserToolbarInteractor
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ internal val browserToolbarInteractor: BrowserToolbarInteractor
get() = _browserToolbarInteractor!!
@VisibleForTesting
@@ -269,6 +277,13 @@ abstract class BaseBrowserFragment :
private var currentStartDownloadDialog: StartDownloadDialog? = null
+ private lateinit var savedLoginsLauncher: ActivityResultLauncher
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ savedLoginsLauncher = registerForActivityResult { navigateToSavedLoginsFragment() }
+ }
+
@CallSuper
override fun onCreateView(
inflater: LayoutInflater,
@@ -419,6 +434,7 @@ abstract class BaseBrowserFragment :
},
)
val browserToolbarMenuController = DefaultBrowserToolbarMenuController(
+ fragment = this,
store = store,
activity = activity,
navController = findNavController(),
@@ -439,7 +455,8 @@ abstract class BaseBrowserFragment :
tabCollectionStorage = requireComponents.core.tabCollectionStorage,
topSitesStorage = requireComponents.core.topSitesStorage,
pinnedSiteStorage = requireComponents.core.pinnedSiteStorage,
- browserStore = store,
+ onShowPinVerification = { intent -> savedLoginsLauncher.launch(intent) },
+ onBiometricAuthenticationSuccessful = { navigateToSavedLoginsFragment() },
)
_browserToolbarInteractor = DefaultBrowserToolbarInteractor(
@@ -485,7 +502,11 @@ abstract class BaseBrowserFragment :
},
)
- if (IncompleteRedesignToolbarFeature(context.settings()).isEnabled) {
+ // We don't show the navigation bar for tablets and in landscape mode.
+ val shouldAddNavigationBar = IncompleteRedesignToolbarFeature(context.settings()).isEnabled &&
+ !requireContext().isLandscape() &&
+ !isTablet()
+ if (shouldAddNavigationBar) {
initializeNavBar(
browserToolbar = browserToolbarView.view,
view = view,
@@ -756,6 +777,9 @@ abstract class BaseBrowserFragment :
loginValidationDelegate = DefaultLoginValidationDelegate(
context.components.core.lazyPasswordsStorage,
),
+ isLoginAutofillEnabled = {
+ context.settings().shouldAutofillLogins
+ },
isSaveLoginEnabled = {
context.settings().shouldPromptToSaveLogins
},
@@ -836,6 +860,7 @@ abstract class BaseBrowserFragment :
feature = SessionFeature(
requireComponents.core.store,
requireComponents.useCases.sessionUseCases.goBack,
+ requireComponents.useCases.sessionUseCases.goForward,
binding.engineView,
customTabSessionId,
),
@@ -1005,7 +1030,9 @@ abstract class BaseBrowserFragment :
)
initializeEngineView(
- topToolbarHeight = context.settings().getTopToolbarHeight(includeTabStrip = customTabSessionId == null),
+ topToolbarHeight = context.settings().getTopToolbarHeight(
+ includeTabStrip = customTabSessionId == null && context.isTabStripEnabled(),
+ ),
bottomToolbarHeight = bottomToolbarHeight,
)
}
@@ -1221,7 +1248,7 @@ abstract class BaseBrowserFragment :
topToolbarHeight = topToolbarHeight,
)
} else {
- val toolbarHeight = if (customTabSessionId == null && context.settings().isTabletAndTabStripEnabled) {
+ val toolbarHeight = if (customTabSessionId == null && context.isTabStripEnabled()) {
resources.getDimensionPixelSize(R.dimen.browser_toolbar_height) +
resources.getDimensionPixelSize(R.dimen.tab_strip_height)
} else {
@@ -1348,7 +1375,9 @@ abstract class BaseBrowserFragment :
onMenuButtonClick = {
findNavController().nav(
R.id.browserFragment,
- BrowserFragmentDirections.actionGlobalMenuDialogFragment(),
+ BrowserFragmentDirections.actionGlobalMenuDialogFragment(
+ accesspoint = MenuAccessPoint.Browser,
+ ),
)
},
)
@@ -1513,6 +1542,11 @@ abstract class BaseBrowserFragment :
removeSessionIfNeeded()
}
+ @CallSuper
+ override fun onForwardPressed(): Boolean {
+ return sessionFeature.onForwardPressed()
+ }
+
/**
* Forwards activity results to the [ActivityResultHandler] features.
*/
@@ -1523,12 +1557,24 @@ abstract class BaseBrowserFragment :
).any { it.onActivityResult(requestCode, data, resultCode) }
}
- override fun onBackLongPressed(): Boolean {
+ /**
+ * Navigate to GlobalTabHistoryDialogFragment.
+ */
+ private fun navigateToGlobalTabHistoryDialogFragment() {
findNavController().navigate(
NavGraphDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSessionId,
),
)
+ }
+
+ override fun onBackLongPressed(): Boolean {
+ navigateToGlobalTabHistoryDialogFragment()
+ return true
+ }
+
+ override fun onForwardLongPressed(): Boolean {
+ navigateToGlobalTabHistoryDialogFragment()
return true
}
@@ -1773,7 +1819,7 @@ abstract class BaseBrowserFragment :
browserToolbarView.visible()
initializeEngineView(
topToolbarHeight = requireContext().settings().getTopToolbarHeight(
- includeTabStrip = customTabSessionId == null,
+ includeTabStrip = customTabSessionId == null && requireContext().isTabStripEnabled(),
),
bottomToolbarHeight = requireContext().settings().getBottomToolbarHeight(),
)
@@ -1787,6 +1833,27 @@ abstract class BaseBrowserFragment :
@CallSuper
internal open fun onUpdateToolbarForConfigurationChange(toolbar: BrowserToolbarView) {
toolbar.dismissMenu()
+
+ // If the navbar feature could be visible, we should update it's state.
+ val shouldUpdateNavBarState =
+ IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled && !isTablet()
+ if (shouldUpdateNavBarState) {
+ updateNavBarForConfigurationChange(
+ parent = binding.browserLayout,
+ toolbarView = browserToolbarView.view,
+ bottomToolbarContainerView = _bottomToolbarContainerView?.toolbarContainerView,
+ reinitializeNavBar = ::reinitializeNavBar,
+ )
+ }
+ }
+
+ private fun reinitializeNavBar() {
+ initializeNavBar(
+ browserToolbar = browserToolbarView.view,
+ view = requireView(),
+ context = requireContext(),
+ activity = requireActivity() as HomeActivity,
+ )
}
/*
@@ -1939,4 +2006,13 @@ abstract class BaseBrowserFragment :
}
}
}
+
+ private fun navigateToSavedLoginsFragment() {
+ val navController = findNavController()
+ if (navController.currentDestination?.id == R.id.browserFragment) {
+ Logins.openLogins.record(NoExtras())
+ val directions = BrowserFragmentDirections.actionLoginsListFragment()
+ navController.navigate(directions)
+ }
+ }
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index 325d537220..89929ed7d1 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -34,11 +34,14 @@ import mozilla.components.feature.tabs.WindowFeature
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
+import mozilla.components.support.utils.ext.isLandscape
+import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.GleanMetrics.AddressToolbar
import org.mozilla.fenix.GleanMetrics.ReaderMode
import org.mozilla.fenix.GleanMetrics.Shopping
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.appstate.AppAction
@@ -51,6 +54,8 @@ import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeFragment
+import org.mozilla.fenix.messaging.FenixMessageSurfaceId
+import org.mozilla.fenix.messaging.MessagingFeature
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.getCookieBannerUIMode
import org.mozilla.fenix.shopping.DefaultShoppingExperienceFeature
@@ -72,12 +77,17 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
private val reviewQualityCheckFeature = ViewBoundFeatureWrapper()
private val translationsBinding = ViewBoundFeatureWrapper()
+ @VisibleForTesting
+ internal val messagingFeature = ViewBoundFeatureWrapper()
+
private var readerModeAvailable = false
private var reviewQualityCheckAvailable = false
private var translationsAvailable = false
private var pwaOnboardingObserver: PwaOnboardingObserver? = null
+ @VisibleForTesting
+ internal var leadingAction: BrowserToolbar.Button? = null
private var forwardAction: BrowserToolbar.TwoStateButton? = null
private var backAction: BrowserToolbar.TwoStateButton? = null
private var refreshAction: BrowserToolbar.TwoStateButton? = null
@@ -89,9 +99,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val context = requireContext()
val components = context.components
- val isTabletAndTabStripEnabled = context.settings().isTabletAndTabStripEnabled
- if (!isTabletAndTabStripEnabled && context.settings().isSwipeToolbarToSwitchTabsEnabled) {
+ if (!context.isTabStripEnabled() && context.settings().isSwipeToolbarToSwitchTabsEnabled) {
binding.gestureLayout.addGestureListener(
ToolbarGestureHandler(
activity = requireActivity(),
@@ -107,15 +116,14 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
)
}
- if (!IncompleteRedesignToolbarFeature(context.settings()).isEnabled) {
- val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
- initLeadingAction(
- context = context,
- isPrivate = isPrivate,
- )
- }
-
- updateToolbarActions(isTablet = resources.getBoolean(R.bool.tablet))
+ updateBrowserToolbarLeadingAndNavigationActions(
+ context = context,
+ redesignEnabled = IncompleteRedesignToolbarFeature(context.settings()).isEnabled,
+ isLandscape = context.isLandscape(),
+ isTablet = resources.getBoolean(R.bool.tablet),
+ isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate,
+ feltPrivateBrowsingEnabled = context.settings().feltPrivateBrowsingEnabled,
+ )
val readerModeAction =
BrowserToolbar.ToggleButton(
@@ -210,6 +218,22 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
)
setTranslationFragmentResultListener()
+
+ setupMicrosurvey()
+ }
+
+ @VisibleForTesting
+ internal fun setupMicrosurvey(isMicrosurveyEnabled: Boolean = FeatureFlags.microsurveysEnabled) {
+ if (requireContext().settings().isExperimentationEnabled && isMicrosurveyEnabled) {
+ messagingFeature.set(
+ feature = MessagingFeature(
+ appStore = requireComponents.appStore,
+ surface = FenixMessageSurfaceId.MICROSURVEY,
+ ),
+ owner = viewLifecycleOwner,
+ view = binding.root,
+ )
+ }
}
private fun setTranslationFragmentResultListener() {
@@ -310,7 +334,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
private fun initReloadAction(context: Context) {
- if (!IncompleteRedesignToolbarFeature(context.settings()).isEnabled || refreshAction != null) {
+ if (!IncompleteRedesignToolbarFeature(context.settings()).isEnabled) {
return
}
@@ -412,43 +436,138 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
// Adds a home button to BrowserToolbar or, if FeltPrivateBrowsing is enabled, a clear data button instead.
- private fun initLeadingAction(
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal fun addLeadingAction(
context: Context,
+ feltPrivateBrowsingEnabled: Boolean,
isPrivate: Boolean,
) {
- val leadingAction = if (isPrivate && context.settings().feltPrivateBrowsingEnabled) {
- BrowserToolbar.Button(
- imageDrawable = AppCompatResources.getDrawable(
- context,
- R.drawable.mozac_ic_data_clearance_24,
- )!!,
- contentDescription = context.getString(R.string.browser_toolbar_erase),
- iconTintColorResource = ThemeManager.resolveAttribute(R.attr.textPrimary, context),
- listener = browserToolbarInteractor::onEraseButtonClicked,
+ if (leadingAction == null) {
+ leadingAction = if (isPrivate && feltPrivateBrowsingEnabled) {
+ BrowserToolbar.Button(
+ imageDrawable = AppCompatResources.getDrawable(
+ context,
+ R.drawable.mozac_ic_data_clearance_24,
+ )!!,
+ contentDescription = context.getString(R.string.browser_toolbar_erase),
+ iconTintColorResource = ThemeManager.resolveAttribute(R.attr.textPrimary, context),
+ listener = browserToolbarInteractor::onEraseButtonClicked,
+ )
+ } else {
+ BrowserToolbar.Button(
+ imageDrawable = AppCompatResources.getDrawable(
+ context,
+ R.drawable.mozac_ic_home_24,
+ )!!,
+ contentDescription = context.getString(R.string.browser_toolbar_home),
+ iconTintColorResource = ThemeManager.resolveAttribute(R.attr.textPrimary, context),
+ listener = browserToolbarInteractor::onHomeButtonClicked,
+ )
+ }.also {
+ browserToolbarView.view.addNavigationAction(it)
+ }
+ }
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal fun removeLeadingAction() {
+ leadingAction?.let {
+ browserToolbarView.view.removeNavigationAction(it)
+ }
+ leadingAction = null
+ }
+
+ /**
+ * This code takes care of the [BrowserToolbar] leading and navigation actions.
+ * The older design requires a HomeButton followed by navigation buttons for tablets.
+ * The newer design expects NavigationButtons and a HomeButton in landscape mode for phones and in both modes
+ * for tablets.
+ */
+ @VisibleForTesting
+ internal fun updateBrowserToolbarLeadingAndNavigationActions(
+ context: Context,
+ redesignEnabled: Boolean,
+ isLandscape: Boolean,
+ isTablet: Boolean,
+ isPrivate: Boolean,
+ feltPrivateBrowsingEnabled: Boolean,
+ ) {
+ if (redesignEnabled) {
+ updateAddressBarNavigationActions(
+ isLandscape = isLandscape,
+ isTablet = isTablet,
+ context = context,
+ )
+ updateAddressBarLeadingAction(
+ redesignEnabled = true,
+ isLandscape = isLandscape,
+ isTablet = isTablet,
+ isPrivate = isPrivate,
+ feltPrivateBrowsingEnabled = feltPrivateBrowsingEnabled,
+ context = context,
)
} else {
- BrowserToolbar.Button(
- imageDrawable = AppCompatResources.getDrawable(
- context,
- R.drawable.mozac_ic_home_24,
- )!!,
- contentDescription = context.getString(R.string.browser_toolbar_home),
- iconTintColorResource = ThemeManager.resolveAttribute(R.attr.textPrimary, context),
- listener = browserToolbarInteractor::onHomeButtonClicked,
+ updateAddressBarLeadingAction(
+ redesignEnabled = false,
+ isLandscape = isLandscape,
+ isPrivate = isPrivate,
+ isTablet = isTablet,
+ feltPrivateBrowsingEnabled = feltPrivateBrowsingEnabled,
+ context = context,
)
+ updateTabletToolbarActions(isTablet = isTablet)
}
+ browserToolbarView.view.invalidateActions()
+ }
- browserToolbarView.view.addNavigationAction(leadingAction)
+ @VisibleForTesting
+ internal fun updateAddressBarLeadingAction(
+ redesignEnabled: Boolean,
+ isLandscape: Boolean,
+ isTablet: Boolean,
+ isPrivate: Boolean,
+ feltPrivateBrowsingEnabled: Boolean,
+ context: Context,
+ ) {
+ if (!redesignEnabled || isLandscape || isTablet) {
+ addLeadingAction(
+ isPrivate = isPrivate,
+ feltPrivateBrowsingEnabled = feltPrivateBrowsingEnabled,
+ context = context,
+ )
+ } else {
+ removeLeadingAction()
+ }
+ }
+
+ @VisibleForTesting
+ internal fun updateAddressBarNavigationActions(
+ context: Context,
+ isLandscape: Boolean,
+ isTablet: Boolean,
+ ) {
+ if (isLandscape || isTablet) {
+ addNavigationActions(context)
+ } else {
+ removeNavigationActions()
+ }
}
override fun onUpdateToolbarForConfigurationChange(toolbar: BrowserToolbarView) {
super.onUpdateToolbarForConfigurationChange(toolbar)
- updateToolbarActions(isTablet = resources.getBoolean(R.bool.tablet))
+ updateBrowserToolbarLeadingAndNavigationActions(
+ context = requireContext(),
+ redesignEnabled = IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled,
+ isLandscape = requireContext().isLandscape(),
+ isTablet = resources.getBoolean(R.bool.tablet),
+ isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate,
+ feltPrivateBrowsingEnabled = requireContext().settings().feltPrivateBrowsingEnabled,
+ )
}
@VisibleForTesting
- internal fun updateToolbarActions(isTablet: Boolean) {
+ internal fun updateTabletToolbarActions(isTablet: Boolean) {
if (isTablet == this.isTablet) return
if (isTablet) {
@@ -460,8 +579,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
this.isTablet = isTablet
}
- @Suppress("LongMethod")
- private fun addTabletActions(context: Context) {
+ @VisibleForTesting
+ internal fun addNavigationActions(context: Context) {
val enableTint = ThemeManager.resolveAttribute(R.attr.textPrimary, context)
val disableTint = ThemeManager.resolveAttribute(R.attr.textDisabled, context)
@@ -486,11 +605,9 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
ToolbarMenu.Item.Back(viewHistory = false),
)
},
- )
- }
-
- backAction?.let {
- browserToolbarView.view.addNavigationAction(it)
+ ).also {
+ browserToolbarView.view.addNavigationAction(it)
+ }
}
if (forwardAction == null) {
@@ -514,13 +631,17 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
ToolbarMenu.Item.Forward(viewHistory = false),
)
},
- )
+ ).also {
+ browserToolbarView.view.addNavigationAction(it)
+ }
}
+ }
- forwardAction?.let {
- browserToolbarView.view.addNavigationAction(it)
- }
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal fun addTabletActions(context: Context) {
+ addNavigationActions(context)
+ val enableTint = ThemeManager.resolveAttribute(R.attr.textPrimary, context)
if (refreshAction == null) {
refreshAction = BrowserToolbar.TwoStateButton(
primaryImage = AppCompatResources.getDrawable(
@@ -552,28 +673,31 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
)
}
},
- )
- }
-
- refreshAction?.let {
- browserToolbarView.view.addNavigationAction(it)
+ ).also {
+ browserToolbarView.view.addNavigationAction(it)
+ }
}
-
- browserToolbarView.view.invalidateActions()
}
- private fun removeTabletActions() {
+ @VisibleForTesting
+ internal fun removeNavigationActions() {
forwardAction?.let {
browserToolbarView.view.removeNavigationAction(it)
}
+ forwardAction = null
backAction?.let {
browserToolbarView.view.removeNavigationAction(it)
}
+ backAction = null
+ }
+
+ @VisibleForTesting
+ internal fun removeTabletActions() {
+ removeNavigationActions()
+
refreshAction?.let {
browserToolbarView.view.removeNavigationAction(it)
}
-
- browserToolbarView.view.invalidateActions()
}
override fun onStart() {
@@ -607,6 +731,10 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
override fun onDestroyView() {
super.onDestroyView()
isTablet = false
+ leadingAction = null
+ forwardAction = null
+ backAction = null
+ refreshAction = null
}
private fun updateHistoryMetadata() {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/StandardSnackbarErrorBinding.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/StandardSnackbarErrorBinding.kt
index 80fbcd61b9..c103e22026 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/StandardSnackbarErrorBinding.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/StandardSnackbarErrorBinding.kt
@@ -59,7 +59,7 @@ class StandardSnackbarErrorBinding(
snackBar.setSnackBarTextColor(
ContextCompat.getColor(
activity,
- R.color.fx_mobile_text_color_warning,
+ R.color.fx_mobile_text_color_critical,
),
)
snackBar.setAction(
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/SwipeGestureLayout.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/SwipeGestureLayout.kt
index a661d1ea1c..e2d36bffed 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/SwipeGestureLayout.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/SwipeGestureLayout.kt
@@ -10,7 +10,6 @@ import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.FrameLayout
-import androidx.core.view.GestureDetectorCompat
/**
* Interface that allows intercepting and handling swipe gestures received in a [SwipeGestureLayout].
@@ -101,7 +100,7 @@ class SwipeGestureLayout @JvmOverloads constructor(
}
}
- private val gestureDetector = GestureDetectorCompat(context, gestureListener)
+ private val gestureDetector = GestureDetector(context, gestureListener)
private val listeners = mutableListOf()
private var activeListener: SwipeGestureListener? = null
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt
index 42b6924955..cc855c9fa2 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt
@@ -110,7 +110,9 @@ class TabPreview @JvmOverloads constructor(
},
)
- removeView(binding.fakeToolbar)
+ if (!isToolbarAtTop) {
+ removeView(binding.fakeToolbar)
+ }
}
// Change view properties to avoid confusing the UI tests
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripFeatureFlag.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripFeatureFlag.kt
new file mode 100644
index 0000000000..faeb5446f5
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripFeatureFlag.kt
@@ -0,0 +1,31 @@
+/* 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.browser.tabstrip
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Build
+import org.mozilla.fenix.Config
+import org.mozilla.fenix.ext.isTablet
+import org.mozilla.fenix.ext.settings
+
+/**
+ * Returns true if the tab strip is enabled.
+ */
+fun Context.isTabStripEnabled(): Boolean =
+ isTabStripEligible() && settings().isTabStripEnabled
+
+/**
+ * Returns true if the the device has the prerequisites to enable the tab strip.
+ */
+fun Context.isTabStripEligible(): Boolean =
+ Config.channel.isNightlyOrDebug && isTablet() && !doesDeviceHaveHinge()
+
+/**
+ * Check if the device has a hinge sensor.
+ */
+private fun Context.doesDeviceHaveHinge(): Boolean =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
+ packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt
index fcd624eec8..099b24a744 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt
@@ -19,6 +19,7 @@ import mozilla.components.concept.sync.DeviceCapability
import mozilla.components.concept.sync.DeviceConfig
import mozilla.components.concept.sync.DeviceType
import mozilla.components.concept.sync.OAuthAccount
+import mozilla.components.feature.accounts.push.CloseTabsFeature
import mozilla.components.feature.accounts.push.FxaPushSupportFeature
import mozilla.components.feature.accounts.push.SendTabFeature
import mozilla.components.feature.syncedtabs.SyncedTabsAutocompleteProvider
@@ -84,7 +85,12 @@ class BackgroundServices(
// NB: flipping this flag back and worth is currently not well supported and may need hand-holding.
// Consult with the android-components peers before changing.
// See https://github.com/mozilla/application-services/issues/1308
- capabilities = setOf(DeviceCapability.SEND_TAB),
+ capabilities = buildSet {
+ add(DeviceCapability.SEND_TAB)
+ if (context.settings().enableCloseSyncedTabs) {
+ add(DeviceCapability.CLOSE_TABS)
+ }
+ },
// Enable encryption for account state on supported API levels (23+).
// Just on Nightly and local builds for now.
@@ -194,6 +200,12 @@ class BackgroundServices(
notificationManager.showReceivedTabs(context, device, tabs)
}
+ if (context.settings().enableCloseSyncedTabs) {
+ CloseTabsFeature(context.components.core.store, accountManager) { _, remotelyClosedUrls ->
+ notificationManager.showSyncedTabsClosed(context, remotelyClosedUrls.size)
+ }.observe()
+ }
+
SyncedTabsIntegration(context, accountManager).launch()
syncStoreSupport = SyncStoreSupport(syncStore, lazyOf(accountManager)).also {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
index 0f6f107df1..35c18e98ea 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
@@ -202,7 +202,7 @@ class Components(private val context: Context) {
collections = core.tabCollectionStorage.cachedTabCollections,
expandedCollections = emptySet(),
topSites = core.topSitesStorage.cachedTopSites.sort(),
- recentBookmarks = emptyList(),
+ bookmarks = emptyList(),
showCollectionPlaceholder = settings.showCollectionsPlaceholderOnHome,
// Provide an initial state for recent tabs to prevent re-rendering on the home screen.
// This will otherwise cause a visual jump as the section gets rendered from no state
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt
index 426019b8eb..9ed2abdcae 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/NotificationManager.kt
@@ -17,11 +17,15 @@ import android.os.Build.VERSION.SDK_INT
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService
+import androidx.core.os.bundleOf
import mozilla.components.concept.sync.Device
import mozilla.components.concept.sync.TabData
+import mozilla.components.support.base.ids.SharedIdsHelper
import mozilla.components.support.base.log.logger.Logger
+import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.IntentReceiverActivity
import org.mozilla.fenix.R
+import org.mozilla.fenix.home.intent.OpenRecentlyClosedIntentProcessor
import org.mozilla.fenix.utils.IntentUtils
/**
@@ -29,6 +33,9 @@ import org.mozilla.fenix.utils.IntentUtils
*/
class NotificationManager(private val context: Context) {
companion object {
+ const val TABS_CLOSED_TAG = "TabsClosed"
+ const val TOTAL_TABS_CLOSED_EXTRA = "org.mozilla.fenix.TOTAL_TABS_CLOSED_EXTRA"
+ const val TABS_CLOSED_NOTIFICATION_TAG = "org.mozilla.fenix.TABS_CLOSED_NOTIFICATION_TAG"
const val RECEIVE_TABS_TAG = "ReceivedTabs"
const val RECEIVE_TABS_CHANNEL_ID = "ReceivedTabsChannel"
}
@@ -51,6 +58,73 @@ class NotificationManager(private val context: Context) {
private val logger = Logger("NotificationManager")
+ /**
+ * Notifies the user that one or more tabs on this device were closed from another device.
+ *
+ * @param context The Android application context.
+ * @param count The number of tabs that were closed.
+ */
+ fun showSyncedTabsClosed(context: Context, count: Int) {
+ if (count <= 0) {
+ return
+ }
+ val notificationManagerCompat = NotificationManagerCompat.from(context)
+ val (notificationId, totalCount) = if (SDK_INT >= Build.VERSION_CODES.M) {
+ // On Android M (released in 2015) and later, we can retrieve
+ // the last notification from `allNotifications`. If one exists,
+ // we'll update its contents in-place with the new total number of
+ // closed tabs.
+ val notificationId = SharedIdsHelper.getIdForTag(context, TABS_CLOSED_NOTIFICATION_TAG)
+ val lastNotification = notificationManagerCompat.activeNotifications.find {
+ it.tag == TABS_CLOSED_TAG && it.id == notificationId
+ }
+ val lastTotalCount = lastNotification?.notification?.extras?.getInt(TOTAL_TABS_CLOSED_EXTRA) ?: 0
+ Pair(notificationId, lastTotalCount + count)
+ } else {
+ // Pre-M doesn't have `activeNotifications`, so we'll show
+ // a new notification for each call to `showSyncedTabsClosed`.
+ val notificationId = SharedIdsHelper.getNextIdForTag(context, TABS_CLOSED_NOTIFICATION_TAG)
+ Pair(notificationId, count)
+ }
+
+ val notification = NotificationCompat.Builder(context, RECEIVE_TABS_CHANNEL_ID).apply {
+ val title = context.resources.getString(
+ R.string.fxa_tabs_closed_notification_title,
+ context.resources.getString(R.string.app_name),
+ totalCount,
+ )
+ setContentTitle(title)
+
+ val text = context.resources.getString(R.string.fxa_tabs_closed_text)
+ setContentText(text)
+
+ val intent = Intent(context, HomeActivity::class.java).apply {
+ action = OpenRecentlyClosedIntentProcessor.ACTION_OPEN_RECENTLY_CLOSED
+ }
+ val pendingIntent = PendingIntent.getActivity(
+ context,
+ 0,
+ intent,
+ IntentUtils.defaultIntentPendingFlags or PendingIntent.FLAG_UPDATE_CURRENT,
+ )
+ setContentIntent(pendingIntent)
+
+ val extras = bundleOf(TOTAL_TABS_CLOSED_EXTRA to totalCount)
+ addExtras(extras)
+
+ setSmallIcon(R.drawable.ic_status_logo)
+ setWhen(System.currentTimeMillis())
+ setAutoCancel(true)
+ setDefaults(Notification.DEFAULT_VIBRATE or Notification.DEFAULT_SOUND)
+
+ if (SDK_INT >= Build.VERSION_CODES.M) {
+ setCategory(Notification.CATEGORY_STATUS)
+ }
+ }.build()
+
+ notificationManagerCompat.notify(TABS_CLOSED_TAG, notificationId, notification)
+ }
+
fun showReceivedTabs(context: Context, device: Device?, tabs: List) {
// In the future, experiment with displaying multiple tabs from the same device as as Notification Groups.
// For now, a single notification per tab received will suffice.
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt
index dbdeb831ed..f813ad33bd 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt
@@ -17,9 +17,9 @@ import org.mozilla.fenix.browser.StandardSnackbarError
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.shopping.ShoppingState
+import org.mozilla.fenix.home.bookmarks.Bookmark
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesSelectedCategory
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTab
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
import org.mozilla.fenix.home.recenttabs.RecentTab
@@ -54,7 +54,7 @@ sealed class AppAction : Action {
val collections: List,
val showCollectionPlaceholder: Boolean,
val recentTabs: List,
- val recentBookmarks: List,
+ val bookmarks: List,
val recentHistory: List,
val recentSyncedTabState: RecentSyncedTabState,
) :
@@ -68,8 +68,16 @@ sealed class AppAction : Action {
data class TopSitesChange(val topSites: List) : AppAction()
data class RecentTabsChange(val recentTabs: List) : AppAction()
data class RemoveRecentTab(val recentTab: RecentTab) : AppAction()
- data class RecentBookmarksChange(val recentBookmarks: List) : AppAction()
- data class RemoveRecentBookmark(val recentBookmark: RecentBookmark) : AppAction()
+
+ /**
+ * The list of bookmarks displayed on the home screen has changed.
+ */
+ data class BookmarksChange(val bookmarks: List) : AppAction()
+
+ /**
+ * A bookmark has been removed from the home screen.
+ */
+ data class RemoveBookmark(val bookmark: Bookmark) : AppAction()
data class RecentHistoryChange(val recentHistory: List) : AppAction()
data class RemoveRecentHistoryHighlight(val highlightUrl: String) : AppAction()
data class DisbandSearchGroupAction(val searchTerm: String) : AppAction()
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt
index e118dca121..dc3a1b368a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt
@@ -16,9 +16,9 @@ import org.mozilla.fenix.browser.StandardSnackbarError
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.appstate.shopping.ShoppingState
import org.mozilla.fenix.home.HomeFragment
+import org.mozilla.fenix.home.bookmarks.Bookmark
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesSelectedCategory
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
import org.mozilla.fenix.home.recenttabs.RecentTab
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
@@ -45,7 +45,7 @@ import org.mozilla.fenix.wallpapers.WallpaperState
* @property showCollectionPlaceholder If true, shows a placeholder when there are no collections.
* @property recentTabs The list of recent [RecentTab] in the [HomeFragment].
* @property recentSyncedTabState The [RecentSyncedTabState] in the [HomeFragment].
- * @property recentBookmarks The list of recently saved [BookmarkNode]s to show on the [HomeFragment].
+ * @property bookmarks The list of recently saved [BookmarkNode]s to show on the [HomeFragment].
* @property recentHistory The list of [RecentlyVisitedItem]s.
* @property pocketStories The list of currently shown [PocketRecommendedStory]s.
* @property pocketStoriesCategories All [PocketRecommendedStory] categories.
@@ -75,7 +75,7 @@ data class AppState(
val showCollectionPlaceholder: Boolean = false,
val recentTabs: List = emptyList(),
val recentSyncedTabState: RecentSyncedTabState = RecentSyncedTabState.None,
- val recentBookmarks: List = emptyList(),
+ val bookmarks: List = emptyList(),
val recentHistory: List = emptyList(),
val pocketStories: List = emptyList(),
val pocketStoriesCategories: List = emptyList(),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt
index a614689982..1092de97f0 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt
@@ -43,7 +43,7 @@ internal object AppStoreReducer {
collections = action.collections,
mode = action.mode,
topSites = action.topSites,
- recentBookmarks = action.recentBookmarks,
+ bookmarks = action.bookmarks,
recentTabs = action.recentTabs,
recentHistory = action.recentHistory,
recentSyncedTabState = action.recentSyncedTabState,
@@ -81,9 +81,9 @@ internal object AppStoreReducer {
recentSyncedTabState = action.state,
)
}
- is AppAction.RecentBookmarksChange -> state.copy(recentBookmarks = action.recentBookmarks)
- is AppAction.RemoveRecentBookmark -> {
- state.copy(recentBookmarks = state.recentBookmarks.filterNot { it.url == action.recentBookmark.url })
+ is AppAction.BookmarksChange -> state.copy(bookmarks = action.bookmarks)
+ is AppAction.RemoveBookmark -> {
+ state.copy(bookmarks = state.bookmarks.filterNot { it.url == action.bookmark.url })
}
is AppAction.RecentHistoryChange -> state.copy(
recentHistory = action.recentHistory,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/bookmarks/BookmarksUseCase.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/bookmarks/BookmarksUseCase.kt
index f8ea604c34..986b4ba3b9 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/bookmarks/BookmarksUseCase.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/bookmarks/BookmarksUseCase.kt
@@ -9,7 +9,7 @@ import mozilla.appservices.places.BookmarkRoot
import mozilla.appservices.places.uniffi.PlacesApiException
import mozilla.components.concept.storage.BookmarksStorage
import mozilla.components.concept.storage.HistoryStorage
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
+import org.mozilla.fenix.home.bookmarks.Bookmark
import java.util.concurrent.TimeUnit
/**
@@ -20,12 +20,17 @@ class BookmarksUseCase(
historyStorage: HistoryStorage,
) {
+ /**
+ * Use case for adding a new bookmark.
+ *
+ * @param storage [BookmarksStorage] used to add and retrieve bookmark data.
+ */
class AddBookmarksUseCase internal constructor(private val storage: BookmarksStorage) {
/**
* Adds a new bookmark with the provided [url] and [title].
*
- * @return The result if the operation was executed or not. A bookmark may not be added if
+ * @return The guid of the newly added bookmark or null. A bookmark may not be added if
* one with the identical [url] already exists.
*/
@WorkerThread
@@ -34,21 +39,22 @@ class BookmarksUseCase(
title: String,
position: UInt? = null,
parentGuid: String? = null,
- ): Boolean {
+ ): String? {
return try {
val canAdd = storage.getBookmarksWithUrl(url).firstOrNull { it.url == url } == null
- if (canAdd) {
+ return if (canAdd) {
storage.addItem(
parentGuid ?: BookmarkRoot.Mobile.id,
url = url,
title = title,
position = position,
)
+ } else {
+ null
}
- canAdd
} catch (e: PlacesApiException.UrlParseFailed) {
- false
+ null
}
}
}
@@ -68,27 +74,26 @@ class BookmarksUseCase(
* Retrieves a list of recently added bookmarks, if any, up to maximum.
*
* @param count The number of recent bookmarks to return.
- * @param maxAgeInMs The maximum age (ms) of a recently added bookmark to return.
- * @return a list of [RecentBookmark] that were added no older than specify by [maxAgeInMs],
- * if any, up to a number specified by [count].
+ * @param previewImageMaxAgeMs The maximum age (ms) to search history for preview image URLs.
+ * @return a list of [Bookmark]s if any, up to a number specified by [count].
*/
@WorkerThread
suspend operator fun invoke(
count: Int = DEFAULT_BOOKMARKS_TO_RETRIEVE,
- maxAgeInMs: Long = TimeUnit.DAYS.toMillis(DEFAULT_BOOKMARKS_DAYS_AGE_TO_RETRIEVE),
- ): List {
+ previewImageMaxAgeMs: Long = TimeUnit.DAYS.toMillis(DEFAULT_BOOKMARKS_LENGTH_DAYS_PREVIEW_IMAGE_SEARCH),
+ ): List {
val currentTime = System.currentTimeMillis()
// Fetch visit information within the time range of now and the specified maximum age.
val history = historyStorage?.getDetailedVisits(
- start = currentTime - maxAgeInMs,
+ start = currentTime - previewImageMaxAgeMs,
end = currentTime,
)
return bookmarksStorage
- .getRecentBookmarks(count, maxAgeInMs)
+ .getRecentBookmarks(count)
.map { bookmark ->
- RecentBookmark(
+ Bookmark(
title = bookmark.title,
url = bookmark.url,
previewImageUrl = history?.find { bookmark.url == it.url }?.previewImageUrl,
@@ -107,9 +112,9 @@ class BookmarksUseCase(
companion object {
// Number of recent bookmarks to retrieve.
- const val DEFAULT_BOOKMARKS_TO_RETRIEVE = 4
+ const val DEFAULT_BOOKMARKS_TO_RETRIEVE = 8
// The maximum age in days of a recent bookmarks to retrieve.
- const val DEFAULT_BOOKMARKS_DAYS_AGE_TO_RETRIEVE = 10L
+ const val DEFAULT_BOOKMARKS_LENGTH_DAYS_PREVIEW_IMAGE_SEARCH = 10L
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/BrowserNavigationParams.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/BrowserNavigationParams.kt
new file mode 100644
index 0000000000..8de758f3d7
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/BrowserNavigationParams.kt
@@ -0,0 +1,18 @@
+/* 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.components.menu
+
+import org.mozilla.fenix.settings.SupportUtils.SumoTopic
+
+/**
+ * Browser navigation parameters of the URL or [SumoTopic] to be loaded.
+ *
+ * @property url The URL to be loaded.
+ * @property sumoTopic The [SumoTopic] to be loaded.
+ */
+data class BrowserNavigationParams(
+ val url: String? = null,
+ val sumoTopic: SumoTopic? = null,
+)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuAccessPoint.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuAccessPoint.kt
new file mode 100644
index 0000000000..f1d8b3a326
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuAccessPoint.kt
@@ -0,0 +1,38 @@
+/* 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.components.menu
+
+import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
+
+/**
+ * The origin access points that was used to navigate to the Menu dialog.
+ */
+enum class MenuAccessPoint {
+ /**
+ * Menu was accessed from the browser.
+ */
+ Browser,
+
+ /**
+ * Menu was accessed from an external app (e.g. custom tab).
+ */
+ External,
+
+ /**
+ * Menu was accessed from the home screen.
+ */
+ Home,
+}
+
+/**
+ * Returns the [FenixFxAEntryPoint] equivalent from the given [MenuAccessPoint].
+ */
+internal fun MenuAccessPoint.toFenixFxAEntryPoint(): FenixFxAEntryPoint {
+ return when (this) {
+ MenuAccessPoint.Browser -> FenixFxAEntryPoint.BrowserToolbar
+ MenuAccessPoint.External -> FenixFxAEntryPoint.Unknown
+ MenuAccessPoint.Home -> FenixFxAEntryPoint.HomeMenu
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt
index 05890cd71d..c0d9d6f11d 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt
@@ -9,25 +9,42 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
import androidx.navigation.fragment.findNavController
+import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import mozilla.components.browser.state.selector.selectedTab
+import mozilla.components.lib.state.ext.observeAsState
+import mozilla.components.service.fxa.manager.AccountState.NotAuthenticated
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
-import org.mozilla.fenix.components.accounts.AccountState
-import org.mozilla.fenix.components.lazyStore
-import org.mozilla.fenix.components.menu.compose.MenuDialog
+import org.mozilla.fenix.components.components
+import org.mozilla.fenix.components.menu.compose.EXTENSIONS_MENU_ROUTE
+import org.mozilla.fenix.components.menu.compose.ExtensionsSubmenu
+import org.mozilla.fenix.components.menu.compose.MAIN_MENU_ROUTE
+import org.mozilla.fenix.components.menu.compose.MainMenu
import org.mozilla.fenix.components.menu.compose.MenuDialogBottomSheet
+import org.mozilla.fenix.components.menu.compose.SAVE_MENU_ROUTE
+import org.mozilla.fenix.components.menu.compose.SaveSubmenu
+import org.mozilla.fenix.components.menu.compose.TOOLS_MENU_ROUTE
+import org.mozilla.fenix.components.menu.compose.ToolsSubmenu
+import org.mozilla.fenix.components.menu.middleware.MenuDialogMiddleware
import org.mozilla.fenix.components.menu.middleware.MenuNavigationMiddleware
+import org.mozilla.fenix.components.menu.store.BrowserMenuState
import org.mozilla.fenix.components.menu.store.MenuAction
import org.mozilla.fenix.components.menu.store.MenuState
import org.mozilla.fenix.components.menu.store.MenuStore
import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.settings.SupportUtils
-import org.mozilla.fenix.settings.SupportUtils.SumoTopic
import org.mozilla.fenix.theme.FirefoxTheme
/**
@@ -35,18 +52,8 @@ import org.mozilla.fenix.theme.FirefoxTheme
*/
class MenuDialogFragment : BottomSheetDialogFragment() {
- private val store by lazyStore { viewModelScope ->
- MenuStore(
- initialState = MenuState(),
- middleware = listOf(
- MenuNavigationMiddleware(
- navController = findNavController(),
- openSumoTopic = ::openSumoTopic,
- scope = viewModelScope,
- ),
- ),
- )
- }
+ private val args by navArgs()
+ private val browsingModeManager get() = (activity as HomeActivity).browsingModeManager
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
super.onCreateDialog(savedInstanceState).apply {
@@ -59,6 +66,7 @@ class MenuDialogFragment : BottomSheetDialogFragment() {
}
}
+ @Suppress("LongMethod")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -69,42 +77,193 @@ class MenuDialogFragment : BottomSheetDialogFragment() {
setContent {
FirefoxTheme {
MenuDialogBottomSheet(onRequestDismiss = {}) {
- MenuDialog(
- account = null,
- accountState = AccountState.NO_ACCOUNT,
- onSignInButtonClick = {},
- onHelpButtonClick = {
- store.dispatch(MenuAction.Navigate.Help)
- },
- onSettingsButtonClick = {
- store.dispatch(MenuAction.Navigate.Settings)
- },
- onBookmarksMenuClick = {
- store.dispatch(MenuAction.Navigate.Bookmarks)
- },
- onHistoryMenuClick = {
- store.dispatch(MenuAction.Navigate.History)
- },
- onDownloadsMenuClick = {
- store.dispatch(MenuAction.Navigate.Downloads)
- },
- onPasswordsMenuClick = {
- store.dispatch(MenuAction.Navigate.Passwords)
- },
- )
+ val browserStore = components.core.store
+ val syncStore = components.backgroundServices.syncStore
+ val bookmarksStorage = components.core.bookmarksStorage
+ val addBookmarkUseCase = components.useCases.bookmarksUseCases.addBookmark
+ val printContentUseCase = components.useCases.sessionUseCases.printContent
+ val saveToPdfUseCase = components.useCases.sessionUseCases.saveToPdf
+ val selectedTab = browserStore.state.selectedTab
+
+ val navHostController = rememberNavController()
+ val coroutineScope = rememberCoroutineScope()
+ val store = remember {
+ MenuStore(
+ initialState = MenuState(
+ browserMenuState = if (selectedTab != null) {
+ BrowserMenuState(selectedTab = selectedTab)
+ } else {
+ null
+ },
+ ),
+ middleware = listOf(
+ MenuDialogMiddleware(
+ bookmarksStorage = bookmarksStorage,
+ addBookmarkUseCase = addBookmarkUseCase,
+ scope = coroutineScope,
+ ),
+ MenuNavigationMiddleware(
+ navController = findNavController(),
+ navHostController = navHostController,
+ browsingModeManager = browsingModeManager,
+ openToBrowser = ::openToBrowser,
+ scope = coroutineScope,
+ ),
+ ),
+ )
+ }
+
+ val account by syncStore.observeAsState(initialValue = null) { state -> state.account }
+ val accountState by syncStore.observeAsState(initialValue = NotAuthenticated) { state ->
+ state.accountState
+ }
+ val isBookmarked by store.observeAsState(initialValue = false) { state ->
+ state.browserMenuState != null && state.browserMenuState.bookmarkState.isBookmarked
+ }
+
+ NavHost(
+ navController = navHostController,
+ startDestination = MAIN_MENU_ROUTE,
+ ) {
+ composable(route = MAIN_MENU_ROUTE) {
+ MainMenu(
+ accessPoint = args.accesspoint,
+ account = account,
+ accountState = accountState,
+ isPrivate = browsingModeManager.mode.isPrivate,
+ onMozillaAccountButtonClick = {
+ store.dispatch(
+ MenuAction.Navigate.MozillaAccount(
+ accountState = accountState,
+ accesspoint = args.accesspoint,
+ ),
+ )
+ },
+ onHelpButtonClick = {
+ store.dispatch(MenuAction.Navigate.Help)
+ },
+ onSettingsButtonClick = {
+ store.dispatch(MenuAction.Navigate.Settings)
+ },
+ onNewTabMenuClick = {
+ store.dispatch(MenuAction.Navigate.NewTab)
+ },
+ onNewPrivateTabMenuClick = {
+ store.dispatch(MenuAction.Navigate.NewPrivateTab)
+ },
+ onSwitchToDesktopSiteMenuClick = {},
+ onFindInPageMenuClick = {},
+ onToolsMenuClick = {
+ store.dispatch(MenuAction.Navigate.Tools)
+ },
+ onSaveMenuClick = {
+ store.dispatch(MenuAction.Navigate.Save)
+ },
+ onExtensionsMenuClick = {
+ store.dispatch(MenuAction.Navigate.Extensions)
+ },
+ onBookmarksMenuClick = {
+ store.dispatch(MenuAction.Navigate.Bookmarks)
+ },
+ onHistoryMenuClick = {
+ store.dispatch(MenuAction.Navigate.History)
+ },
+ onDownloadsMenuClick = {
+ store.dispatch(MenuAction.Navigate.Downloads)
+ },
+ onPasswordsMenuClick = {
+ store.dispatch(MenuAction.Navigate.Passwords)
+ },
+ onCustomizeHomepageMenuClick = {
+ store.dispatch(MenuAction.Navigate.CustomizeHomepage)
+ },
+ onNewInFirefoxMenuClick = {
+ store.dispatch(MenuAction.Navigate.ReleaseNotes)
+ },
+ )
+ }
+
+ composable(route = TOOLS_MENU_ROUTE) {
+ ToolsSubmenu(
+ isReaderViewActive = false,
+ isTranslated = false,
+ onBackButtonClick = {
+ store.dispatch(MenuAction.Navigate.Back)
+ },
+ onReaderViewMenuClick = {},
+ onTranslatePageMenuClick = {
+ selectedTab?.let {
+ store.dispatch(MenuAction.Navigate.Translate)
+ }
+ },
+ onPrintMenuClick = {
+ printContentUseCase()
+ dismiss()
+ },
+ onShareMenuClick = {
+ selectedTab?.let {
+ store.dispatch(MenuAction.Navigate.Share)
+ }
+ },
+ onOpenInAppMenuClick = {},
+ )
+ }
+
+ composable(route = SAVE_MENU_ROUTE) {
+ SaveSubmenu(
+ isBookmarked = isBookmarked,
+ onBackButtonClick = {
+ store.dispatch(MenuAction.Navigate.Back)
+ },
+ onBookmarkPageMenuClick = {
+ store.dispatch(MenuAction.AddBookmark)
+ },
+ onEditBookmarkButtonClick = {
+ store.dispatch(MenuAction.Navigate.EditBookmark)
+ },
+ onAddToShortcutsMenuClick = {},
+ onAddToHomeScreenMenuClick = {},
+ onSaveToCollectionMenuClick = {},
+ onSaveAsPDFMenuClick = {
+ saveToPdfUseCase()
+ dismiss()
+ },
+ )
+ }
+
+ composable(route = EXTENSIONS_MENU_ROUTE) {
+ ExtensionsSubmenu(
+ onBackButtonClick = {
+ store.dispatch(MenuAction.Navigate.Back)
+ },
+ onManageExtensionsMenuClick = {
+ store.dispatch(MenuAction.Navigate.ManageExtensions)
+ },
+ onDiscoverMoreExtensionsMenuClick = {
+ store.dispatch(MenuAction.Navigate.DiscoverMoreExtensions)
+ },
+ )
+ }
+ }
}
}
}
}
- private fun openSumoTopic(topic: SumoTopic) = runIfFragmentIsAttached {
- (activity as HomeActivity).openToBrowserAndLoad(
- searchTermOrURL = SupportUtils.getSumoURLForTopic(
+ private fun openToBrowser(params: BrowserNavigationParams) = runIfFragmentIsAttached {
+ val url = params.url ?: params.sumoTopic?.let {
+ SupportUtils.getSumoURLForTopic(
context = requireContext(),
- topic = topic,
- ),
- newTab = true,
- from = BrowserDirection.FromMenuDialogFragment,
- )
+ topic = it,
+ )
+ }
+
+ url?.let {
+ (activity as HomeActivity).openToBrowserAndLoad(
+ searchTermOrURL = url,
+ newTab = true,
+ from = BrowserDirection.FromMenuDialogFragment,
+ )
+ }
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/ExtensionsSubmenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/ExtensionsSubmenu.kt
new file mode 100644
index 0000000000..2bfffb7103
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/ExtensionsSubmenu.kt
@@ -0,0 +1,101 @@
+/* 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.components.menu.compose
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.menu.compose.header.SubmenuHeader
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.compose.list.TextListItem
+import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
+
+internal const val EXTENSIONS_MENU_ROUTE = "extensions_menu"
+
+@Composable
+internal fun ExtensionsSubmenu(
+ onBackButtonClick: () -> Unit,
+ onManageExtensionsMenuClick: () -> Unit,
+ onDiscoverMoreExtensionsMenuClick: () -> Unit,
+) {
+ Column {
+ SubmenuHeader(
+ header = stringResource(id = R.string.browser_menu_extensions),
+ onClick = onBackButtonClick,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ Column(
+ modifier = Modifier
+ .padding(
+ start = 16.dp,
+ top = 12.dp,
+ end = 16.dp,
+ bottom = 32.dp,
+ ),
+ verticalArrangement = Arrangement.spacedBy(32.dp),
+ ) {
+ MenuGroup {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_manage_extensions),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_extension_cog_24),
+ onClick = onManageExtensionsMenuClick,
+ )
+ }
+
+ MenuGroup {
+ TextListItem(
+ label = stringResource(id = R.string.browser_menu_discover_more_extensions),
+ onClick = onDiscoverMoreExtensionsMenuClick,
+ iconPainter = painterResource(R.drawable.mozac_ic_external_link_24),
+ iconTint = FirefoxTheme.colors.iconSecondary,
+ )
+ }
+ }
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun ExtensionsSubmenuPreview() {
+ FirefoxTheme {
+ Column(
+ modifier = Modifier.background(color = FirefoxTheme.colors.layer3),
+ ) {
+ ExtensionsSubmenu(
+ onBackButtonClick = {},
+ onManageExtensionsMenuClick = {},
+ onDiscoverMoreExtensionsMenuClick = {},
+ )
+ }
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun ExtensionsSubmenuPrivatePreview() {
+ FirefoxTheme(theme = Theme.Private) {
+ Column(
+ modifier = Modifier.background(color = FirefoxTheme.colors.layer3),
+ ) {
+ ExtensionsSubmenu(
+ onBackButtonClick = {},
+ onManageExtensionsMenuClick = {},
+ onDiscoverMoreExtensionsMenuClick = {},
+ )
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MainMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MainMenu.kt
new file mode 100644
index 0000000000..695fbfcbca
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MainMenu.kt
@@ -0,0 +1,365 @@
+/* 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.components.menu.compose
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import mozilla.components.service.fxa.manager.AccountState
+import mozilla.components.service.fxa.manager.AccountState.NotAuthenticated
+import mozilla.components.service.fxa.store.Account
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.menu.MenuAccessPoint
+import org.mozilla.fenix.components.menu.compose.header.MenuHeader
+import org.mozilla.fenix.compose.Divider
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
+
+internal const val MAIN_MENU_ROUTE = "main_menu"
+
+/**
+ * Wrapper column containing the main menu items.
+ *
+ * @param accessPoint The [MenuAccessPoint] that was used to navigate to the menu dialog.
+ * @param account [Account] information available for a synced account.
+ * @param accountState The [AccountState] of a Mozilla account.
+ * @param isPrivate Whether or not the browsing mode is in private mode.
+ * @param onMozillaAccountButtonClick Invoked when the user clicks on Mozilla account button.
+ * @param onHelpButtonClick Invoked when the user clicks on the help button.
+ * @param onSettingsButtonClick Invoked when the user clicks on the settings button.
+ * @param onNewTabMenuClick Invoked when the user clicks on the new tab menu item.
+ * @param onNewPrivateTabMenuClick Invoked when the user clicks on the new private tab menu item.
+ * @param onSwitchToDesktopSiteMenuClick Invoked when the user clicks on the switch to desktop site
+ * menu toggle.
+ * @param onFindInPageMenuClick Invoked when the user clicks on the find in page menu item.
+ * @param onToolsMenuClick Invoked when the user clicks on the tools menu item.
+ * @param onSaveMenuClick Invoked when the user clicks on the save menu item.
+ * @param onExtensionsMenuClick Invoked when the user clicks on the extensions menu item.
+ * @param onBookmarksMenuClick Invoked when the user clicks on the bookmarks menu item.
+ * @param onHistoryMenuClick Invoked when the user clicks on the history menu item.
+ * @param onDownloadsMenuClick Invoked when the user clicks on the downloads menu item.
+ * @param onPasswordsMenuClick Invoked when the user clicks on the passwords menu item.
+ * @param onCustomizeHomepageMenuClick Invoked when the user clicks on the customize
+ * homepage menu item.
+ * @param onNewInFirefoxMenuClick Invoked when the user clicks on the release note menu item.
+ */
+@Suppress("LongParameterList")
+@Composable
+internal fun MainMenu(
+ accessPoint: MenuAccessPoint,
+ account: Account?,
+ accountState: AccountState,
+ isPrivate: Boolean,
+ onMozillaAccountButtonClick: () -> Unit,
+ onHelpButtonClick: () -> Unit,
+ onSettingsButtonClick: () -> Unit,
+ onNewTabMenuClick: () -> Unit,
+ onNewPrivateTabMenuClick: () -> Unit,
+ onSwitchToDesktopSiteMenuClick: () -> Unit,
+ onFindInPageMenuClick: () -> Unit,
+ onToolsMenuClick: () -> Unit,
+ onSaveMenuClick: () -> Unit,
+ onExtensionsMenuClick: () -> Unit,
+ onBookmarksMenuClick: () -> Unit,
+ onHistoryMenuClick: () -> Unit,
+ onDownloadsMenuClick: () -> Unit,
+ onPasswordsMenuClick: () -> Unit,
+ onCustomizeHomepageMenuClick: () -> Unit,
+ onNewInFirefoxMenuClick: () -> Unit,
+) {
+ Column {
+ MenuHeader(
+ account = account,
+ accountState = accountState,
+ onMozillaAccountButtonClick = onMozillaAccountButtonClick,
+ onHelpButtonClick = onHelpButtonClick,
+ onSettingsButtonClick = onSettingsButtonClick,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ Column(
+ modifier = Modifier
+ .padding(
+ start = 16.dp,
+ top = 12.dp,
+ end = 16.dp,
+ bottom = 32.dp,
+ ),
+ verticalArrangement = Arrangement.spacedBy(32.dp),
+ ) {
+ NewTabsMenuGroup(
+ accessPoint = accessPoint,
+ isPrivate = isPrivate,
+ onNewTabMenuClick = onNewTabMenuClick,
+ onNewPrivateTabMenuClick = onNewPrivateTabMenuClick,
+ )
+
+ ToolsAndActionsMenuGroup(
+ accessPoint = accessPoint,
+ onSwitchToDesktopSiteMenuClick = onSwitchToDesktopSiteMenuClick,
+ onFindInPageMenuClick = onFindInPageMenuClick,
+ onToolsMenuClick = onToolsMenuClick,
+ onSaveMenuClick = onSaveMenuClick,
+ onExtensionsMenuClick = onExtensionsMenuClick,
+ )
+
+ LibraryMenuGroup(
+ onBookmarksMenuClick = onBookmarksMenuClick,
+ onHistoryMenuClick = onHistoryMenuClick,
+ onDownloadsMenuClick = onDownloadsMenuClick,
+ onPasswordsMenuClick = onPasswordsMenuClick,
+ )
+
+ if (accessPoint == MenuAccessPoint.Home) {
+ HomepageMenuGroup(
+ onCustomizeHomepageMenuClick = onCustomizeHomepageMenuClick,
+ onNewInFirefoxMenuClick = onNewInFirefoxMenuClick,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun NewTabsMenuGroup(
+ accessPoint: MenuAccessPoint,
+ isPrivate: Boolean,
+ onNewTabMenuClick: () -> Unit,
+ onNewPrivateTabMenuClick: () -> Unit,
+) {
+ val isNewTabMenuEnabled: Boolean
+ val isNewPrivateTabMenuEnabled: Boolean
+
+ when (accessPoint) {
+ MenuAccessPoint.Browser,
+ MenuAccessPoint.External,
+ -> {
+ isNewTabMenuEnabled = true
+ isNewPrivateTabMenuEnabled = true
+ }
+
+ MenuAccessPoint.Home -> {
+ isNewTabMenuEnabled = isPrivate
+ isNewPrivateTabMenuEnabled = !isPrivate
+ }
+ }
+
+ MenuGroup {
+ MenuItem(
+ label = stringResource(id = R.string.library_new_tab),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_plus_24),
+ state = if (isNewTabMenuEnabled) MenuItemState.ENABLED else MenuItemState.DISABLED,
+ onClick = onNewTabMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_new_private_tab),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_private_mode_circle_fill_24),
+ state = if (isNewPrivateTabMenuEnabled) MenuItemState.ENABLED else MenuItemState.DISABLED,
+ onClick = onNewPrivateTabMenuClick,
+ )
+ }
+}
+
+@Composable
+private fun ToolsAndActionsMenuGroup(
+ accessPoint: MenuAccessPoint,
+ onSwitchToDesktopSiteMenuClick: () -> Unit,
+ onFindInPageMenuClick: () -> Unit,
+ onToolsMenuClick: () -> Unit,
+ onSaveMenuClick: () -> Unit,
+ onExtensionsMenuClick: () -> Unit,
+) {
+ MenuGroup {
+ if (accessPoint == MenuAccessPoint.Browser) {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_switch_to_desktop_site),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_device_desktop_24),
+ onClick = onSwitchToDesktopSiteMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_find_in_page_2),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_search_24),
+ onClick = onFindInPageMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_tools),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_tool_24),
+ onClick = onToolsMenuClick,
+ afterIconPainter = painterResource(id = R.drawable.mozac_ic_chevron_right_24),
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_save),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_save_24),
+ onClick = onSaveMenuClick,
+ afterIconPainter = painterResource(id = R.drawable.mozac_ic_chevron_right_24),
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+ }
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_extensions),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_extension_24),
+ onClick = onExtensionsMenuClick,
+ afterIconPainter = painterResource(id = R.drawable.mozac_ic_chevron_right_24),
+ )
+ }
+}
+
+@Composable
+private fun LibraryMenuGroup(
+ onBookmarksMenuClick: () -> Unit,
+ onHistoryMenuClick: () -> Unit,
+ onDownloadsMenuClick: () -> Unit,
+ onPasswordsMenuClick: () -> Unit,
+) {
+ MenuGroup {
+ MenuItem(
+ label = stringResource(id = R.string.library_bookmarks),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_tray_fill_24),
+ onClick = onBookmarksMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.library_history),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_history_24),
+ onClick = onHistoryMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.library_downloads),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_download_24),
+ onClick = onDownloadsMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_passwords),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_login_24),
+ onClick = onPasswordsMenuClick,
+ )
+ }
+}
+
+@Composable
+private fun HomepageMenuGroup(
+ onCustomizeHomepageMenuClick: () -> Unit,
+ onNewInFirefoxMenuClick: () -> Unit,
+) {
+ MenuGroup {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_customize_home_1),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_grid_add_24),
+ onClick = onCustomizeHomepageMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(
+ id = R.string.browser_menu_new_in_firefox,
+ stringResource(id = R.string.app_name),
+ ),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_whats_new_24),
+ onClick = onNewInFirefoxMenuClick,
+ )
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun MenuDialogPreview() {
+ FirefoxTheme {
+ Column(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer3),
+ ) {
+ MainMenu(
+ accessPoint = MenuAccessPoint.Home,
+ account = null,
+ accountState = NotAuthenticated,
+ isPrivate = false,
+ onMozillaAccountButtonClick = {},
+ onHelpButtonClick = {},
+ onSettingsButtonClick = {},
+ onNewTabMenuClick = {},
+ onNewPrivateTabMenuClick = {},
+ onSwitchToDesktopSiteMenuClick = {},
+ onFindInPageMenuClick = {},
+ onToolsMenuClick = {},
+ onSaveMenuClick = {},
+ onExtensionsMenuClick = {},
+ onBookmarksMenuClick = {},
+ onHistoryMenuClick = {},
+ onDownloadsMenuClick = {},
+ onPasswordsMenuClick = {},
+ onCustomizeHomepageMenuClick = {},
+ onNewInFirefoxMenuClick = {},
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun MenuDialogPrivatePreview() {
+ FirefoxTheme(theme = Theme.Private) {
+ Column(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer3),
+ ) {
+ MainMenu(
+ accessPoint = MenuAccessPoint.Home,
+ account = null,
+ accountState = NotAuthenticated,
+ isPrivate = false,
+ onMozillaAccountButtonClick = {},
+ onHelpButtonClick = {},
+ onSettingsButtonClick = {},
+ onNewTabMenuClick = {},
+ onNewPrivateTabMenuClick = {},
+ onSwitchToDesktopSiteMenuClick = {},
+ onFindInPageMenuClick = {},
+ onToolsMenuClick = {},
+ onSaveMenuClick = {},
+ onExtensionsMenuClick = {},
+ onBookmarksMenuClick = {},
+ onHistoryMenuClick = {},
+ onDownloadsMenuClick = {},
+ onPasswordsMenuClick = {},
+ onCustomizeHomepageMenuClick = {},
+ onNewInFirefoxMenuClick = {},
+ )
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuDialog.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuDialog.kt
deleted file mode 100644
index a9747fce84..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuDialog.kt
+++ /dev/null
@@ -1,203 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.components.menu.compose
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import mozilla.components.service.fxa.store.Account
-import org.mozilla.fenix.R
-import org.mozilla.fenix.components.accounts.AccountState
-import org.mozilla.fenix.components.accounts.AccountState.NO_ACCOUNT
-import org.mozilla.fenix.components.menu.compose.header.MenuHeader
-import org.mozilla.fenix.compose.Divider
-import org.mozilla.fenix.compose.annotation.LightDarkPreview
-import org.mozilla.fenix.compose.list.IconListItem
-import org.mozilla.fenix.theme.FirefoxTheme
-import org.mozilla.fenix.theme.Theme
-
-/**
- * The menu bottom sheet dialog.
- *
- * @param account [Account] information available for a synced account.
- * @param accountState The [AccountState] of a synced account.
- * @param onSignInButtonClick Invoked when the user clicks on the "Sign in" button.
- * @param onHelpButtonClick Invoked when the user clicks on the help button.
- * @param onSettingsButtonClick Invoked when the user clicks on the settings button.
- * @param onBookmarksMenuClick Invoked when the user clicks on the bookmarks menu item.
- * @param onHistoryMenuClick Invoked when the user clicks on the history menu item.
- * @param onDownloadsMenuClick Invoked when the user clicks on the downloads menu item.
- * @param onPasswordsMenuClick Invoked when the user clicks on the passwords menu item.
- */
-@Suppress("LongParameterList")
-@Composable
-fun MenuDialog(
- account: Account?,
- accountState: AccountState,
- onSignInButtonClick: () -> Unit,
- onHelpButtonClick: () -> Unit,
- onSettingsButtonClick: () -> Unit,
- onBookmarksMenuClick: () -> Unit,
- onHistoryMenuClick: () -> Unit,
- onDownloadsMenuClick: () -> Unit,
- onPasswordsMenuClick: () -> Unit,
-) {
- Column {
- MenuHeader(
- account = account,
- accountState = accountState,
- onSignInButtonClick = onSignInButtonClick,
- onHelpButtonClick = onHelpButtonClick,
- onSettingsButtonClick = onSettingsButtonClick,
- )
-
- Spacer(modifier = Modifier.height(8.dp))
-
- MainMenu(
- onBookmarksMenuClick = onBookmarksMenuClick,
- onHistoryMenuClick = onHistoryMenuClick,
- onDownloadsMenuClick = onDownloadsMenuClick,
- onPasswordsMenuClick = onPasswordsMenuClick,
- )
- }
-}
-
-/**
- * Wrapper column containing the main menu items.
- */
-@Composable
-private fun MainMenu(
- onBookmarksMenuClick: () -> Unit,
- onHistoryMenuClick: () -> Unit,
- onDownloadsMenuClick: () -> Unit,
- onPasswordsMenuClick: () -> Unit,
-) {
- Column(
- modifier = Modifier
- .padding(
- start = 16.dp,
- top = 12.dp,
- end = 16.dp,
- bottom = 32.dp,
- ),
- verticalArrangement = Arrangement.spacedBy(32.dp),
- ) {
- MenuGroup {
- IconListItem(
- label = stringResource(id = R.string.library_new_tab),
- beforeIconPainter = painterResource(id = R.drawable.mozac_ic_plus_24),
- )
-
- Divider(color = FirefoxTheme.colors.borderSecondary)
-
- IconListItem(
- label = stringResource(id = R.string.browser_menu_new_private_tab),
- beforeIconPainter = painterResource(id = R.drawable.mozac_ic_private_mode_circle_fill_24),
- )
- }
-
- LibraryMenuGroup(
- onBookmarksMenuClick = onBookmarksMenuClick,
- onHistoryMenuClick = onHistoryMenuClick,
- onDownloadsMenuClick = onDownloadsMenuClick,
- onPasswordsMenuClick = onPasswordsMenuClick,
- )
- }
-}
-
-@Composable
-private fun LibraryMenuGroup(
- onBookmarksMenuClick: () -> Unit,
- onHistoryMenuClick: () -> Unit,
- onDownloadsMenuClick: () -> Unit,
- onPasswordsMenuClick: () -> Unit,
-) {
- MenuGroup {
- IconListItem(
- label = stringResource(id = R.string.library_bookmarks),
- onClick = onBookmarksMenuClick,
- beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_tray_fill_24),
- )
-
- Divider(color = FirefoxTheme.colors.borderSecondary)
-
- IconListItem(
- label = stringResource(id = R.string.library_history),
- onClick = onHistoryMenuClick,
- beforeIconPainter = painterResource(id = R.drawable.mozac_ic_history_24),
- )
-
- Divider(color = FirefoxTheme.colors.borderSecondary)
-
- IconListItem(
- label = stringResource(id = R.string.library_downloads),
- onClick = onDownloadsMenuClick,
- beforeIconPainter = painterResource(id = R.drawable.mozac_ic_download_24),
- )
-
- Divider(color = FirefoxTheme.colors.borderSecondary)
-
- IconListItem(
- label = stringResource(id = R.string.browser_menu_passwords),
- onClick = onPasswordsMenuClick,
- beforeIconPainter = painterResource(id = R.drawable.mozac_ic_login_24),
- )
- }
-}
-
-@LightDarkPreview
-@Composable
-private fun MenuDialogPreview() {
- FirefoxTheme {
- Column(
- modifier = Modifier
- .background(color = FirefoxTheme.colors.layer3),
- ) {
- MenuDialog(
- account = null,
- accountState = NO_ACCOUNT,
- onSignInButtonClick = {},
- onHelpButtonClick = {},
- onSettingsButtonClick = {},
- onBookmarksMenuClick = {},
- onHistoryMenuClick = {},
- onDownloadsMenuClick = {},
- onPasswordsMenuClick = {},
- )
- }
- }
-}
-
-@Preview
-@Composable
-private fun MenuDialogPrivatePreview() {
- FirefoxTheme(theme = Theme.Private) {
- Column(
- modifier = Modifier
- .background(color = FirefoxTheme.colors.layer3),
- ) {
- MenuDialog(
- account = null,
- accountState = NO_ACCOUNT,
- onSignInButtonClick = {},
- onHelpButtonClick = {},
- onSettingsButtonClick = {},
- onBookmarksMenuClick = {},
- onHistoryMenuClick = {},
- onDownloadsMenuClick = {},
- onPasswordsMenuClick = {},
- )
- }
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuGroup.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuGroup.kt
index 1b2fb0ab2f..811ab69db9 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuGroup.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuGroup.kt
@@ -19,7 +19,6 @@ import androidx.compose.ui.unit.dp
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.Divider
import org.mozilla.fenix.compose.annotation.LightDarkPreview
-import org.mozilla.fenix.compose.list.IconListItem
import org.mozilla.fenix.theme.FirefoxTheme
private val ROUNDED_CORNER_SHAPE = RoundedCornerShape(12.dp)
@@ -60,14 +59,14 @@ private fun MenuGroupPreview() {
.padding(16.dp),
) {
MenuGroup {
- IconListItem(
+ MenuItem(
label = stringResource(id = R.string.browser_menu_add_to_homescreen),
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_plus_24),
)
Divider(color = FirefoxTheme.colors.borderSecondary)
- IconListItem(
+ MenuItem(
label = stringResource(id = R.string.browser_menu_add_to_homescreen),
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_plus_24),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuItem.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuItem.kt
new file mode 100644
index 0000000000..41f64670a2
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MenuItem.kt
@@ -0,0 +1,202 @@
+/* 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.components.menu.compose
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.Divider
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.compose.list.IconListItem
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * An [IconListItem] wrapper for menu items in a [MenuGroup] with an optional icon at the end.
+ *
+ * @param label The label in the menu item.
+ * @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
+ * @param beforeIconDescription Content description of the icon.
+ * @param description An optional description text below the label.
+ * @param state The state of the menu item to display.
+ * @param onClick Invoked when the user clicks on the item.
+ * @param afterIconPainter [Painter] used to display an [IconButton] after the list item.
+ * @param afterIconDescription Content description of the icon.
+ */
+@Composable
+internal fun MenuItem(
+ label: String,
+ beforeIconPainter: Painter,
+ beforeIconDescription: String? = null,
+ description: String? = null,
+ state: MenuItemState = MenuItemState.ENABLED,
+ onClick: (() -> Unit)? = null,
+ afterIconPainter: Painter? = null,
+ afterIconDescription: String? = null,
+) {
+ val labelTextColor = getLabelTextColor(state = state)
+ val iconTint = getIconTint(state = state)
+ val enabled = state != MenuItemState.DISABLED
+
+ IconListItem(
+ label = label,
+ labelTextColor = labelTextColor,
+ description = description,
+ enabled = enabled,
+ onClick = onClick,
+ beforeIconPainter = beforeIconPainter,
+ beforeIconDescription = beforeIconDescription,
+ beforeIconTint = iconTint,
+ afterIconPainter = afterIconPainter,
+ afterIconDescription = afterIconDescription,
+ afterIconTint = iconTint,
+ )
+}
+
+/**
+ * An [IconListItem] wrapper for menu items in a [MenuGroup] with an optional text button at the end.
+ *
+ * @param label The label in the menu item.
+ * @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
+ * @param beforeIconDescription Content description of the icon.
+ * @param description An optional description text below the label.
+ * @param state The state of the menu item to display.
+ * @param onClick Invoked when the user clicks on the item.
+ * @param afterButtonText The button text to be displayed after the list item.
+ * @param afterButtonTextColor [Color] to apply to [afterButtonText].
+ * @param onAfterButtonClick Called when the user clicks on the text button.
+ */
+@Composable
+internal fun MenuItem(
+ label: String,
+ beforeIconPainter: Painter,
+ beforeIconDescription: String? = null,
+ description: String? = null,
+ state: MenuItemState = MenuItemState.ENABLED,
+ onClick: (() -> Unit)? = null,
+ afterButtonText: String? = null,
+ afterButtonTextColor: Color = FirefoxTheme.colors.actionPrimary,
+ onAfterButtonClick: (() -> Unit)? = null,
+) {
+ val labelTextColor = getLabelTextColor(state = state)
+ val iconTint = getIconTint(state = state)
+ val enabled = state != MenuItemState.DISABLED
+
+ IconListItem(
+ label = label,
+ labelTextColor = labelTextColor,
+ description = description,
+ enabled = enabled,
+ onClick = onClick,
+ beforeIconPainter = beforeIconPainter,
+ beforeIconDescription = beforeIconDescription,
+ beforeIconTint = iconTint,
+ afterButtonText = afterButtonText,
+ afterButtonTextColor = afterButtonTextColor,
+ onAfterButtonClick = onAfterButtonClick,
+ )
+}
+
+/**
+ * Enum containing all the supported state for the menu item.
+ */
+enum class MenuItemState {
+ /**
+ * The menu item is enabled.
+ */
+ ENABLED,
+
+ /**
+ * The menu item is disabled and is not clickable.
+ */
+ DISABLED,
+
+ /**
+ * The menu item is highlighted to indicate the feature behind the menu item is active.
+ */
+ ACTIVE,
+
+ /**
+ * The menu item is highlighted to indicate the feature behind the menu item is destructive.
+ */
+ WARNING,
+}
+
+@Composable
+private fun getLabelTextColor(state: MenuItemState): Color {
+ return when (state) {
+ MenuItemState.ACTIVE -> FirefoxTheme.colors.textAccent
+ MenuItemState.WARNING -> FirefoxTheme.colors.textCritical
+ else -> FirefoxTheme.colors.textPrimary
+ }
+}
+
+@Composable
+private fun getIconTint(state: MenuItemState): Color {
+ return when (state) {
+ MenuItemState.ACTIVE -> FirefoxTheme.colors.iconAccentViolet
+ MenuItemState.WARNING -> FirefoxTheme.colors.iconCritical
+ else -> FirefoxTheme.colors.iconSecondary
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun MenuItemPreview() {
+ FirefoxTheme {
+ Column(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer3)
+ .padding(16.dp),
+ ) {
+ MenuGroup {
+ for (state in MenuItemState.entries) {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_translations),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_translate_24),
+ state = state,
+ onClick = {},
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+ }
+
+ for (state in MenuItemState.entries) {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_extensions),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_extension_24),
+ state = state,
+ onClick = {},
+ afterIconPainter = painterResource(id = R.drawable.mozac_ic_chevron_right_24),
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+ }
+
+ for (state in MenuItemState.entries) {
+ MenuItem(
+ label = stringResource(id = R.string.library_bookmarks),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_tray_fill_24),
+ state = state,
+ onClick = {},
+ afterButtonText = stringResource(id = R.string.browser_menu_edit),
+ onAfterButtonClick = {},
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+ }
+ }
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/SaveSubmenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/SaveSubmenu.kt
new file mode 100644
index 0000000000..9ceda75cea
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/SaveSubmenu.kt
@@ -0,0 +1,163 @@
+/* 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.components.menu.compose
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.menu.compose.header.SubmenuHeader
+import org.mozilla.fenix.compose.Divider
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
+
+internal const val SAVE_MENU_ROUTE = "save_menu"
+
+@Suppress("LongParameterList")
+@Composable
+internal fun SaveSubmenu(
+ isBookmarked: Boolean,
+ onBackButtonClick: () -> Unit,
+ onBookmarkPageMenuClick: () -> Unit,
+ onEditBookmarkButtonClick: () -> Unit,
+ onAddToShortcutsMenuClick: () -> Unit,
+ onAddToHomeScreenMenuClick: () -> Unit,
+ onSaveToCollectionMenuClick: () -> Unit,
+ onSaveAsPDFMenuClick: () -> Unit,
+) {
+ Column {
+ SubmenuHeader(
+ header = stringResource(id = R.string.browser_menu_save),
+ onClick = onBackButtonClick,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ Column(
+ modifier = Modifier
+ .padding(
+ start = 16.dp,
+ top = 12.dp,
+ end = 16.dp,
+ bottom = 32.dp,
+ ),
+ verticalArrangement = Arrangement.spacedBy(32.dp),
+ ) {
+ MenuGroup {
+ BookmarkMenuItem(
+ isBookmarked = isBookmarked,
+ onBookmarkPageMenuClick = onBookmarkPageMenuClick,
+ onEditBookmarkButtonClick = onEditBookmarkButtonClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_add_to_shortcuts),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_pin_24),
+ onClick = onAddToShortcutsMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_add_to_homescreen_2),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_add_to_homescreen_24),
+ onClick = onAddToHomeScreenMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_save_to_collection),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_collection_24),
+ onClick = onSaveToCollectionMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_save_as_pdf),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_save_file_24),
+ onClick = onSaveAsPDFMenuClick,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun BookmarkMenuItem(
+ isBookmarked: Boolean,
+ onBookmarkPageMenuClick: () -> Unit,
+ onEditBookmarkButtonClick: () -> Unit,
+) {
+ if (isBookmarked) {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_edit_bookmark),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_fill_24),
+ state = MenuItemState.ACTIVE,
+ onClick = onEditBookmarkButtonClick,
+ )
+ } else {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_bookmark_this_page),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_24),
+ onClick = onBookmarkPageMenuClick,
+ )
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun SaveSubmenuPreview() {
+ FirefoxTheme {
+ Column(
+ modifier = Modifier.background(color = FirefoxTheme.colors.layer3),
+ ) {
+ SaveSubmenu(
+ isBookmarked = false,
+ onBackButtonClick = {},
+ onBookmarkPageMenuClick = {},
+ onEditBookmarkButtonClick = {},
+ onAddToShortcutsMenuClick = {},
+ onAddToHomeScreenMenuClick = {},
+ onSaveToCollectionMenuClick = {},
+ onSaveAsPDFMenuClick = {},
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun SaveSubmenuPrivatePreview() {
+ FirefoxTheme(theme = Theme.Private) {
+ Column(
+ modifier = Modifier.background(color = FirefoxTheme.colors.layer3),
+ ) {
+ SaveSubmenu(
+ isBookmarked = false,
+ onBackButtonClick = {},
+ onBookmarkPageMenuClick = {},
+ onEditBookmarkButtonClick = {},
+ onAddToShortcutsMenuClick = {},
+ onAddToHomeScreenMenuClick = {},
+ onSaveToCollectionMenuClick = {},
+ onSaveAsPDFMenuClick = {},
+ )
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/ToolsSubmenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/ToolsSubmenu.kt
new file mode 100644
index 0000000000..7f80d5c3e9
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/ToolsSubmenu.kt
@@ -0,0 +1,184 @@
+/* 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.components.menu.compose
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.menu.compose.header.SubmenuHeader
+import org.mozilla.fenix.compose.Divider
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
+
+internal const val TOOLS_MENU_ROUTE = "tools_menu"
+
+@Suppress("LongParameterList")
+@Composable
+internal fun ToolsSubmenu(
+ isReaderViewActive: Boolean,
+ isTranslated: Boolean,
+ onBackButtonClick: () -> Unit,
+ onReaderViewMenuClick: () -> Unit,
+ onTranslatePageMenuClick: () -> Unit,
+ onPrintMenuClick: () -> Unit,
+ onShareMenuClick: () -> Unit,
+ onOpenInAppMenuClick: () -> Unit,
+) {
+ Column {
+ SubmenuHeader(
+ header = stringResource(id = R.string.browser_menu_tools),
+ onClick = onBackButtonClick,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ Column(
+ modifier = Modifier
+ .padding(
+ start = 16.dp,
+ top = 12.dp,
+ end = 16.dp,
+ bottom = 32.dp,
+ ),
+ verticalArrangement = Arrangement.spacedBy(32.dp),
+ ) {
+ MenuGroup {
+ ReaderViewMenuItem(
+ isReaderViewActive = isReaderViewActive,
+ onClick = onReaderViewMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ TranslationMenuItem(
+ isTranslated = isTranslated,
+ onClick = onTranslatePageMenuClick,
+ )
+ }
+
+ MenuGroup {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_print),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_print_24),
+ onClick = onPrintMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_share_2),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_share_android_24),
+ onClick = onShareMenuClick,
+ )
+
+ Divider(color = FirefoxTheme.colors.borderSecondary)
+
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_open_app_link),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_more_grid_24),
+ onClick = onOpenInAppMenuClick,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun ReaderViewMenuItem(
+ isReaderViewActive: Boolean,
+ onClick: () -> Unit,
+) {
+ if (isReaderViewActive) {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_turn_off_reader_view),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_reader_view_fill_24),
+ state = MenuItemState.ACTIVE,
+ onClick = onClick,
+ )
+ } else {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_turn_on_reader_view),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_reader_view_24),
+ onClick = onClick,
+ )
+ }
+}
+
+@Composable
+private fun TranslationMenuItem(
+ isTranslated: Boolean,
+ onClick: () -> Unit,
+) {
+ if (isTranslated) {
+ MenuItem(
+ label = stringResource(
+ id = R.string.browser_menu_translated_to,
+ stringResource(id = R.string.app_name),
+ ),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_translate_24),
+ state = MenuItemState.ACTIVE,
+ onClick = onClick,
+ )
+ } else {
+ MenuItem(
+ label = stringResource(id = R.string.browser_menu_translate_page),
+ beforeIconPainter = painterResource(id = R.drawable.mozac_ic_translate_24),
+ onClick = onClick,
+ )
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun ToolsSubmenuPreview() {
+ FirefoxTheme {
+ Column(
+ modifier = Modifier.background(color = FirefoxTheme.colors.layer3),
+ ) {
+ ToolsSubmenu(
+ isReaderViewActive = false,
+ isTranslated = false,
+ onBackButtonClick = {},
+ onReaderViewMenuClick = {},
+ onTranslatePageMenuClick = {},
+ onPrintMenuClick = {},
+ onShareMenuClick = {},
+ onOpenInAppMenuClick = {},
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun ToolsSubmenuPrivatePreview() {
+ FirefoxTheme(theme = Theme.Private) {
+ Column(
+ modifier = Modifier.background(color = FirefoxTheme.colors.layer3),
+ ) {
+ ToolsSubmenu(
+ isReaderViewActive = false,
+ isTranslated = false,
+ onBackButtonClick = {},
+ onReaderViewMenuClick = {},
+ onTranslatePageMenuClick = {},
+ onPrintMenuClick = {},
+ onShareMenuClick = {},
+ onOpenInAppMenuClick = {},
+ )
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MenuHeader.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MenuHeader.kt
index 1c31f8b87f..a9391696d9 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MenuHeader.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MenuHeader.kt
@@ -20,10 +20,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import mozilla.components.service.fxa.manager.AccountState
+import mozilla.components.service.fxa.manager.AccountState.NotAuthenticated
import mozilla.components.service.fxa.store.Account
import org.mozilla.fenix.R
-import org.mozilla.fenix.components.accounts.AccountState
-import org.mozilla.fenix.components.accounts.AccountState.NO_ACCOUNT
import org.mozilla.fenix.compose.Divider
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.theme.FirefoxTheme
@@ -33,7 +33,7 @@ import org.mozilla.fenix.theme.Theme
internal fun MenuHeader(
account: Account?,
accountState: AccountState,
- onSignInButtonClick: () -> Unit,
+ onMozillaAccountButtonClick: () -> Unit,
onHelpButtonClick: () -> Unit,
onSettingsButtonClick: () -> Unit,
) {
@@ -46,7 +46,7 @@ internal fun MenuHeader(
MozillaAccountMenuButton(
account = account,
accountState = accountState,
- onSignInButtonClick = onSignInButtonClick,
+ onClick = onMozillaAccountButtonClick,
modifier = Modifier.weight(1f),
)
@@ -86,8 +86,8 @@ private fun MenuHeaderPreview() {
) {
MenuHeader(
account = null,
- accountState = NO_ACCOUNT,
- onSignInButtonClick = {},
+ accountState = NotAuthenticated,
+ onMozillaAccountButtonClick = {},
onHelpButtonClick = {},
onSettingsButtonClick = {},
)
@@ -105,8 +105,8 @@ private fun MenuHeaderPrivatePreview() {
) {
MenuHeader(
account = null,
- accountState = NO_ACCOUNT,
- onSignInButtonClick = {},
+ accountState = NotAuthenticated,
+ onMozillaAccountButtonClick = {},
onHelpButtonClick = {},
onSettingsButtonClick = {},
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MozillaAccountMenuButton.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MozillaAccountMenuButton.kt
index 9cf00e248a..4e8663c81a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MozillaAccountMenuButton.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/MozillaAccountMenuButton.kt
@@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.Text
@@ -24,24 +26,28 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import mozilla.components.service.fxa.manager.AccountState
+import mozilla.components.service.fxa.manager.AccountState.Authenticated
+import mozilla.components.service.fxa.manager.AccountState.Authenticating
+import mozilla.components.service.fxa.manager.AccountState.AuthenticationProblem
+import mozilla.components.service.fxa.manager.AccountState.NotAuthenticated
import mozilla.components.service.fxa.store.Account
import org.mozilla.fenix.R
-import org.mozilla.fenix.components.accounts.AccountState
-import org.mozilla.fenix.components.accounts.AccountState.AUTHENTICATED
-import org.mozilla.fenix.components.accounts.AccountState.NEEDS_REAUTHENTICATION
-import org.mozilla.fenix.components.accounts.AccountState.NO_ACCOUNT
+import org.mozilla.fenix.compose.Image
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme
private val BUTTON_HEIGHT = 56.dp
private val BUTTON_SHAPE = RoundedCornerShape(size = 8.dp)
+private val ICON_SHAPE = RoundedCornerShape(size = 24.dp)
+private val AVATAR_SIZE = 24.dp
@Composable
internal fun MozillaAccountMenuButton(
account: Account?,
accountState: AccountState,
- onSignInButtonClick: () -> Unit,
+ onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
@@ -51,13 +57,13 @@ internal fun MozillaAccountMenuButton(
shape = BUTTON_SHAPE,
)
.clip(shape = BUTTON_SHAPE)
- .clickable { onSignInButtonClick() }
+ .clickable { onClick() }
.defaultMinSize(minHeight = BUTTON_HEIGHT),
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.width(4.dp))
- AvatarIcon()
+ AvatarIcon(account)
Column(
modifier = Modifier
@@ -65,7 +71,7 @@ internal fun MozillaAccountMenuButton(
.weight(1f),
) {
when (accountState) {
- NO_ACCOUNT -> {
+ NotAuthenticated -> {
Text(
text = stringResource(id = R.string.browser_menu_sign_in),
color = FirefoxTheme.colors.textSecondary,
@@ -81,7 +87,7 @@ internal fun MozillaAccountMenuButton(
)
}
- NEEDS_REAUTHENTICATION -> {
+ AuthenticationProblem -> {
Text(
text = stringResource(id = R.string.browser_menu_sign_back_in_to_sync),
color = FirefoxTheme.colors.textSecondary,
@@ -91,13 +97,13 @@ internal fun MozillaAccountMenuButton(
Text(
text = stringResource(id = R.string.browser_menu_syncing_paused_caption),
- color = FirefoxTheme.colors.textWarning,
+ color = FirefoxTheme.colors.textCritical,
maxLines = 2,
style = FirefoxTheme.typography.caption,
)
}
- AUTHENTICATED -> {
+ Authenticated -> {
Text(
text = account?.displayName ?: account?.email
?: stringResource(id = R.string.browser_menu_account_settings),
@@ -106,14 +112,16 @@ internal fun MozillaAccountMenuButton(
style = FirefoxTheme.typography.headline7,
)
}
+
+ is Authenticating -> Unit
}
}
- if (accountState == NEEDS_REAUTHENTICATION) {
+ if (accountState == AuthenticationProblem) {
Icon(
painter = painterResource(R.drawable.mozac_ic_warning_fill_24),
contentDescription = null,
- tint = FirefoxTheme.colors.iconWarning,
+ tint = FirefoxTheme.colors.iconCritical,
)
Spacer(modifier = Modifier.width(8.dp))
@@ -122,20 +130,44 @@ internal fun MozillaAccountMenuButton(
}
@Composable
-private fun AvatarIcon() {
+private fun FallbackAvatarIcon() {
Icon(
painter = painterResource(id = R.drawable.mozac_ic_avatar_circle_24),
contentDescription = null,
modifier = Modifier
.background(
color = FirefoxTheme.colors.layer2,
- shape = RoundedCornerShape(size = 24.dp),
+ shape = ICON_SHAPE,
)
.padding(all = 4.dp),
tint = FirefoxTheme.colors.iconSecondary,
)
}
+@Composable
+private fun AvatarIcon(account: Account?) {
+ val avatarUrl = account?.avatar?.url
+
+ if (avatarUrl != null) {
+ Image(
+ url = avatarUrl,
+ modifier = Modifier
+ .background(
+ color = FirefoxTheme.colors.layer2,
+ shape = ICON_SHAPE,
+ )
+ .padding(all = 4.dp)
+ .size(AVATAR_SIZE)
+ .clip(CircleShape),
+ targetSize = AVATAR_SIZE,
+ placeholder = { FallbackAvatarIcon() },
+ fallback = { FallbackAvatarIcon() },
+ )
+ } else {
+ FallbackAvatarIcon()
+ }
+}
+
@Composable
private fun MenuHeaderPreviewContent() {
Column(
@@ -146,14 +178,14 @@ private fun MenuHeaderPreviewContent() {
) {
MozillaAccountMenuButton(
account = null,
- accountState = NO_ACCOUNT,
- onSignInButtonClick = {},
+ accountState = NotAuthenticated,
+ onClick = {},
)
MozillaAccountMenuButton(
account = null,
- accountState = NEEDS_REAUTHENTICATION,
- onSignInButtonClick = {},
+ accountState = AuthenticationProblem,
+ onClick = {},
)
MozillaAccountMenuButton(
@@ -165,8 +197,8 @@ private fun MenuHeaderPreviewContent() {
currentDeviceId = null,
sessionToken = null,
),
- accountState = AUTHENTICATED,
- onSignInButtonClick = {},
+ accountState = Authenticated,
+ onClick = {},
)
MozillaAccountMenuButton(
@@ -178,8 +210,8 @@ private fun MenuHeaderPreviewContent() {
currentDeviceId = null,
sessionToken = null,
),
- accountState = AUTHENTICATED,
- onSignInButtonClick = {},
+ accountState = Authenticated,
+ onClick = {},
)
MozillaAccountMenuButton(
@@ -191,8 +223,8 @@ private fun MenuHeaderPreviewContent() {
currentDeviceId = null,
sessionToken = null,
),
- accountState = AUTHENTICATED,
- onSignInButtonClick = {},
+ accountState = Authenticated,
+ onClick = {},
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/SubmenuHeader.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/SubmenuHeader.kt
new file mode 100644
index 0000000000..6b47ea17db
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/header/SubmenuHeader.kt
@@ -0,0 +1,94 @@
+/* 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.components.menu.compose.header
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.semantics.heading
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
+
+@Composable
+internal fun SubmenuHeader(
+ header: String,
+ onClick: () -> Unit,
+) {
+ Row(
+ modifier = Modifier
+ .padding(start = 4.dp, end = 16.dp)
+ .defaultMinSize(minHeight = 56.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ IconButton(
+ onClick = { onClick() },
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.mozac_ic_back_24),
+ contentDescription = null,
+ tint = FirefoxTheme.colors.iconSecondary,
+ )
+ }
+
+ Spacer(modifier = Modifier.width(4.dp))
+
+ Text(
+ text = header,
+ modifier = Modifier
+ .weight(1f)
+ .semantics { heading() },
+ color = FirefoxTheme.colors.textSecondary,
+ style = FirefoxTheme.typography.headline7,
+ )
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun SubmenuHeaderPreview() {
+ FirefoxTheme {
+ Column(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer3),
+ ) {
+ SubmenuHeader(
+ header = "sub-menu header",
+ onClick = {},
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun SubmenuMenuHeaderPrivatePreview() {
+ FirefoxTheme(theme = Theme.Private) {
+ Column(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer3),
+ ) {
+ SubmenuHeader(
+ header = "sub-menu header",
+ onClick = {},
+ )
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuDialogMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuDialogMiddleware.kt
new file mode 100644
index 0000000000..16df4ed576
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuDialogMiddleware.kt
@@ -0,0 +1,93 @@
+/* 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.components.menu.middleware
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import mozilla.components.browser.state.ext.getUrl
+import mozilla.components.concept.storage.BookmarksStorage
+import mozilla.components.lib.state.Middleware
+import mozilla.components.lib.state.MiddlewareContext
+import mozilla.components.lib.state.Store
+import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
+import org.mozilla.fenix.components.menu.store.BookmarkState
+import org.mozilla.fenix.components.menu.store.MenuAction
+import org.mozilla.fenix.components.menu.store.MenuState
+
+/**
+ * [Middleware] implementation for handling [MenuAction] and managing the [MenuState] for the menu
+ * dialog.
+ *
+ * @param bookmarksStorage An instance of the [BookmarksStorage] used
+ * to query matching bookmarks.
+ * @param addBookmarkUseCase The [BookmarksUseCase.AddBookmarksUseCase] for adding the
+ * selected tab as a bookmark.
+ * @param scope [CoroutineScope] used to launch coroutines.
+ */
+class MenuDialogMiddleware(
+ private val bookmarksStorage: BookmarksStorage,
+ private val addBookmarkUseCase: BookmarksUseCase.AddBookmarksUseCase,
+ private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO),
+) : Middleware {
+
+ override fun invoke(
+ context: MiddlewareContext,
+ next: (MenuAction) -> Unit,
+ action: MenuAction,
+ ) {
+ when (action) {
+ is MenuAction.InitAction -> initialize(context.store)
+ is MenuAction.AddBookmark -> addBookmark(context.store)
+ else -> Unit
+ }
+
+ next(action)
+ }
+
+ private fun initialize(
+ store: Store,
+ ) = scope.launch {
+ val url = store.state.browserMenuState?.selectedTab?.content?.url ?: return@launch
+ val bookmark =
+ bookmarksStorage.getBookmarksWithUrl(url).firstOrNull { it.url == url } ?: return@launch
+
+ store.dispatch(
+ MenuAction.UpdateBookmarkState(
+ bookmarkState = BookmarkState(
+ guid = bookmark.guid,
+ isBookmarked = true,
+ ),
+ ),
+ )
+ }
+
+ private fun addBookmark(
+ store: Store,
+ ) = scope.launch {
+ val browserMenuState = store.state.browserMenuState ?: return@launch
+
+ if (browserMenuState.bookmarkState.isBookmarked) {
+ return@launch
+ }
+
+ val selectedTab = browserMenuState.selectedTab
+ val url = selectedTab.getUrl() ?: return@launch
+
+ val guid = addBookmarkUseCase(
+ url = url,
+ title = selectedTab.content.title,
+ )
+
+ store.dispatch(
+ MenuAction.UpdateBookmarkState(
+ BookmarkState(
+ guid = guid,
+ isBookmarked = true,
+ ),
+ ),
+ )
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuNavigationMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuNavigationMiddleware.kt
index 7c0a03d5ab..21a361bd0b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuNavigationMiddleware.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/middleware/MenuNavigationMiddleware.kt
@@ -5,18 +5,35 @@
package org.mozilla.fenix.components.menu.middleware
import androidx.navigation.NavController
+import androidx.navigation.NavHostController
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot
+import mozilla.components.browser.state.ext.getUrl
+import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
+import mozilla.components.service.fxa.manager.AccountState.Authenticated
+import mozilla.components.service.fxa.manager.AccountState.Authenticating
+import mozilla.components.service.fxa.manager.AccountState.AuthenticationProblem
+import mozilla.components.service.fxa.manager.AccountState.NotAuthenticated
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.BrowserFragmentDirections
+import org.mozilla.fenix.browser.browsingmode.BrowsingMode
+import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
+import org.mozilla.fenix.components.menu.BrowserNavigationParams
import org.mozilla.fenix.components.menu.MenuDialogFragmentDirections
+import org.mozilla.fenix.components.menu.compose.EXTENSIONS_MENU_ROUTE
+import org.mozilla.fenix.components.menu.compose.SAVE_MENU_ROUTE
+import org.mozilla.fenix.components.menu.compose.TOOLS_MENU_ROUTE
import org.mozilla.fenix.components.menu.store.MenuAction
import org.mozilla.fenix.components.menu.store.MenuState
import org.mozilla.fenix.components.menu.store.MenuStore
+import org.mozilla.fenix.components.menu.toFenixFxAEntryPoint
import org.mozilla.fenix.ext.nav
+import org.mozilla.fenix.settings.SupportUtils
+import org.mozilla.fenix.settings.SupportUtils.AMO_HOMEPAGE_FOR_ANDROID
import org.mozilla.fenix.settings.SupportUtils.SumoTopic
/**
@@ -24,25 +41,62 @@ import org.mozilla.fenix.settings.SupportUtils.SumoTopic
* dispatched to the [MenuStore].
*
* @param navController [NavController] used for navigation.
- * @param openSumoTopic Callback to open the provided [SumoTopic] in a new browser tab.
+ * @param navHostController [NavHostController] used for Compose navigation.
+ * @param browsingModeManager [BrowsingModeManager] used for setting the browsing mode.
+ * @param openToBrowser Callback to open the provided [BrowserNavigationParams]
+ * in a new browser tab.
* @param scope [CoroutineScope] used to launch coroutines.
*/
class MenuNavigationMiddleware(
private val navController: NavController,
- private val openSumoTopic: (topic: SumoTopic) -> Unit,
+ private val navHostController: NavHostController,
+ private val browsingModeManager: BrowsingModeManager,
+ private val openToBrowser: (params: BrowserNavigationParams) -> Unit,
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Main),
) : Middleware {
+ @Suppress("CyclomaticComplexMethod", "LongMethod")
override fun invoke(
context: MiddlewareContext,
next: (MenuAction) -> Unit,
action: MenuAction,
) {
+ // Get the current state before further processing of the chain of actions.
+ // This is to ensure that any navigation action will be using correct
+ // state properties before they are modified due to other actions being
+ // dispatched and processes.
+ val currentState = context.state
+
next(action)
scope.launch {
when (action) {
- is MenuAction.Navigate.Help -> openSumoTopic(SumoTopic.HELP)
+ is MenuAction.Navigate.MozillaAccount -> {
+ when (action.accountState) {
+ Authenticated -> navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalAccountSettingsFragment(),
+ )
+
+ AuthenticationProblem -> navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalAccountProblemFragment(
+ entrypoint = action.accesspoint.toFenixFxAEntryPoint(),
+ ),
+ )
+
+ is Authenticating, NotAuthenticated -> navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalTurnOnSync(
+ entrypoint = action.accesspoint.toFenixFxAEntryPoint(),
+ ),
+ )
+ }
+ }
+
+ is MenuAction.Navigate.Help -> openToBrowser(
+ BrowserNavigationParams(sumoTopic = SumoTopic.HELP),
+ )
is MenuAction.Navigate.Settings -> navController.nav(
R.id.menuDialogFragment,
@@ -69,8 +123,82 @@ class MenuNavigationMiddleware(
MenuDialogFragmentDirections.actionGlobalSavedLoginsAuthFragment(),
)
+ is MenuAction.Navigate.CustomizeHomepage -> navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalHomeSettingsFragment(),
+ )
+
+ is MenuAction.Navigate.ReleaseNotes -> openToBrowser(
+ BrowserNavigationParams(url = SupportUtils.WHATS_NEW_URL),
+ )
+
+ is MenuAction.Navigate.Tools -> navHostController.navigate(route = TOOLS_MENU_ROUTE)
+
+ is MenuAction.Navigate.Save -> navHostController.navigate(route = SAVE_MENU_ROUTE)
+
+ is MenuAction.Navigate.Extensions -> navHostController.navigate(route = EXTENSIONS_MENU_ROUTE)
+
+ is MenuAction.Navigate.Back -> navHostController.popBackStack()
+
+ is MenuAction.Navigate.EditBookmark -> {
+ currentState.browserMenuState?.bookmarkState?.guid?.let { guidToEdit ->
+ navController.nav(
+ R.id.menuDialogFragment,
+ BrowserFragmentDirections.actionGlobalBookmarkEditFragment(
+ guidToEdit = guidToEdit,
+ requiresSnackbarPaddingForToolbar = true,
+ ),
+ )
+ }
+ }
+
+ is MenuAction.Navigate.Translate -> navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionMenuDialogFragmentToTranslationsDialogFragment(),
+ )
+
+ is MenuAction.Navigate.Share -> {
+ currentState.browserMenuState?.selectedTab?.let { selectedTab ->
+ navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalShareFragment(
+ sessionId = selectedTab.id,
+ data = arrayOf(
+ ShareData(
+ url = selectedTab.getUrl(),
+ title = selectedTab.content.title,
+ ),
+ ),
+ showPage = true,
+ ),
+ )
+ }
+ }
+
+ is MenuAction.Navigate.ManageExtensions -> navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalAddonsManagementFragment(),
+ )
+
+ is MenuAction.Navigate.DiscoverMoreExtensions -> openToBrowser(
+ BrowserNavigationParams(url = AMO_HOMEPAGE_FOR_ANDROID),
+ )
+
+ is MenuAction.Navigate.NewTab -> openNewTab(isPrivate = false)
+
+ is MenuAction.Navigate.NewPrivateTab -> openNewTab(isPrivate = true)
+
else -> Unit
}
}
}
+
+ private fun openNewTab(isPrivate: Boolean) {
+ browsingModeManager.mode = BrowsingMode.fromBoolean(isPrivate)
+
+ navController.nav(
+ R.id.menuDialogFragment,
+ MenuDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true),
+ )
+ }
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuAction.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuAction.kt
index 1400deeae1..021bb63687 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuAction.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuAction.kt
@@ -5,6 +5,8 @@
package org.mozilla.fenix.components.menu.store
import mozilla.components.lib.state.Action
+import mozilla.components.service.fxa.manager.AccountState
+import org.mozilla.fenix.components.menu.MenuAccessPoint
/**
* Actions to dispatch through the [MenuStore] to modify the [MenuState].
@@ -12,17 +14,41 @@ import mozilla.components.lib.state.Action
sealed class MenuAction : Action {
/**
- * Updates whether or not the current selected tab is bookmarked.
+ * [MenuAction] dispatched to indicate that the store is initialized and
+ * ready to use. This action is dispatched automatically before any other
+ * action is processed. Its main purpose is to trigger initialization logic
+ * in middlewares.
+ */
+ data object InitAction : MenuAction()
+
+ /**
+ * [MenuAction] dispatched when a bookmark is to be added.
+ */
+ data object AddBookmark : MenuAction()
+
+ /**
+ * [MenuAction] dispatched when a bookmark state is updated.
*
- * @property isBookmarked Whether or not the current selected is bookmarked.
+ * @property bookmarkState The new [BookmarkState] to be updated.
*/
- data class UpdateBookmarked(val isBookmarked: Boolean) : MenuAction()
+ data class UpdateBookmarkState(val bookmarkState: BookmarkState) : MenuAction()
/**
* [MenuAction] dispatched when a navigation event occurs for a specific destination.
*/
sealed class Navigate : MenuAction() {
+ /**
+ * [Navigate] action dispatched when navigating to Mozilla account.
+ *
+ * @property accountState The [AccountState] of a Mozilla account.
+ * @property accesspoint The access point that was used to navigate to the menu.
+ */
+ data class MozillaAccount(
+ val accountState: AccountState,
+ val accesspoint: MenuAccessPoint,
+ ) : Navigate()
+
/**
* [Navigate] action dispatched when navigating to the help SUMO article.
*/
@@ -52,5 +78,70 @@ sealed class MenuAction : Action {
* [Navigate] action dispatched when navigating to passwords.
*/
data object Passwords : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to customize homepage.
+ */
+ data object CustomizeHomepage : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to release notes.
+ */
+ data object ReleaseNotes : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the tools submenu.
+ */
+ data object Tools : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the save submenu.
+ */
+ data object Save : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the extensions submenu.
+ */
+ data object Extensions : Navigate()
+
+ /**
+ * [Navigate] action dispatched when a back navigation event occurs.
+ */
+ data object Back : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to edit the existing bookmark.
+ */
+ data object EditBookmark : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to translations dialog.
+ */
+ data object Translate : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the share sheet.
+ */
+ data object Share : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the extensions manager.
+ */
+ data object ManageExtensions : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the AMO page.
+ */
+ data object DiscoverMoreExtensions : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the new tab.
+ */
+ data object NewTab : Navigate()
+
+ /**
+ * [Navigate] action dispatched when navigating to the new private tab.
+ */
+ data object NewPrivateTab : Navigate()
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuState.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuState.kt
index 0f5b7a61e3..7635eebaae 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuState.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuState.kt
@@ -4,13 +4,36 @@
package org.mozilla.fenix.components.menu.store
+import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.lib.state.State
/**
* Value type that represents the state of the menu.
*
- * @property isBookmarked Whether or not the current selected tab is bookmarked.
+ * @property browserMenuState The [BrowserMenuState] of the current browser session if any.
*/
data class MenuState(
- val isBookmarked: Boolean = false,
+ val browserMenuState: BrowserMenuState? = null,
) : State
+
+/**
+ * Value type that represents the state of the browser menu.
+ *
+ * @property selectedTab The current selected [TabSessionState].
+ * @property bookmarkState The [BookmarkState] of the selected tab.
+ */
+data class BrowserMenuState(
+ val selectedTab: TabSessionState,
+ val bookmarkState: BookmarkState = BookmarkState(),
+)
+
+/**
+ * Value type that represents the bookmark state of a tab.
+ *
+ * @property guid The id of the bookmark.
+ * @property isBookmarked Whether or not the selected tab is bookmarked.
+ */
+data class BookmarkState(
+ val guid: String? = null,
+ val isBookmarked: Boolean = false,
+)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuStore.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuStore.kt
index 14cca54e61..bc2c5b9037 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuStore.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/store/MenuStore.kt
@@ -4,6 +4,7 @@
package org.mozilla.fenix.components.menu.store
+import androidx.annotation.VisibleForTesting
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.Store
@@ -13,16 +14,32 @@ import mozilla.components.lib.state.Store
class MenuStore(
initialState: MenuState,
middleware: List> = listOf(),
-) :
- Store(
- initialState = initialState,
- reducer = ::reducer,
- middleware = middleware,
- )
+) : Store(
+ initialState = initialState,
+ reducer = ::reducer,
+ middleware = middleware,
+) {
+ init {
+ dispatch(MenuAction.InitAction)
+ }
+}
private fun reducer(state: MenuState, action: MenuAction): MenuState {
return when (action) {
- is MenuAction.UpdateBookmarked -> state.copy(isBookmarked = action.isBookmarked)
- is MenuAction.Navigate -> state
+ is MenuAction.InitAction,
+ is MenuAction.AddBookmark,
+ is MenuAction.Navigate,
+ -> state
+
+ is MenuAction.UpdateBookmarkState -> state.copyWithBrowserMenuState {
+ it.copy(bookmarkState = action.bookmarkState)
+ }
}
}
+
+@VisibleForTesting
+internal inline fun MenuState.copyWithBrowserMenuState(
+ crossinline update: (BrowserMenuState) -> BrowserMenuState,
+): MenuState {
+ return this.copy(browserMenuState = this.browserMenuState?.let { update(it) })
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt
index 63cec2f8d7..78e3a7c44c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt
@@ -6,6 +6,7 @@ package org.mozilla.fenix.components.toolbar
import androidx.navigation.NavController
import mozilla.components.browser.state.action.ContentAction
+import mozilla.components.browser.state.ext.getUrl
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
@@ -233,18 +234,20 @@ class DefaultBrowserToolbarController(
override fun handleTranslationsButtonClick() {
Translations.action.record(Translations.ActionExtra("main_flow_toolbar"))
val directions =
- BrowserFragmentDirections.actionBrowserFragmentToTranslationsDialogFragment(
- sessionId = currentSession?.id,
- )
+ BrowserFragmentDirections.actionBrowserFragmentToTranslationsDialogFragment()
navController.navigateSafe(R.id.browserFragment, directions)
}
override fun onShareActionClicked() {
+ val sessionId = currentSession?.id
+ val url = sessionId?.let {
+ store.state.findTab(it)?.getUrl()
+ }
val directions = NavGraphDirections.actionGlobalShareFragment(
- sessionId = currentSession?.id,
+ sessionId = sessionId,
data = arrayOf(
ShareData(
- url = getProperUrl(currentSession),
+ url = url,
title = currentSession?.content?.title,
),
),
@@ -253,17 +256,6 @@ class DefaultBrowserToolbarController(
navController.navigate(directions)
}
- private fun getProperUrl(currentSession: SessionState?): String? {
- return currentSession?.id?.let {
- val currentTab = store.state.findTab(it)
- if (currentTab?.readerState?.active == true) {
- currentTab.readerState.activeUrl
- } else {
- currentSession.content.url
- }
- }
- }
-
companion object {
internal const val TELEMETRY_BROWSER_IDENTIFIER = "browserMenu"
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt
index 56d65453fe..a214718ba1 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt
@@ -8,6 +8,7 @@ import android.content.Intent
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.CoroutineScope
@@ -16,10 +17,10 @@ import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.state.action.EngineAction
+import mozilla.components.browser.state.ext.getUrl
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.selector.selectedTab
-import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.EngineSession.LoadUrlFlags
import mozilla.components.concept.engine.prompt.ShareData
@@ -51,6 +52,7 @@ import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.navigateSafe
import org.mozilla.fenix.ext.openSetDefaultBrowserOption
+import org.mozilla.fenix.settings.biometric.bindBiometricsCredentialsPromptOrShowWarning
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.utils.Settings
@@ -63,6 +65,7 @@ interface BrowserToolbarMenuController {
@Suppress("LargeClass", "ForbiddenComment", "LongParameterList")
class DefaultBrowserToolbarMenuController(
+ private val fragment: Fragment,
private val store: BrowserStore,
private val activity: HomeActivity,
private val navController: NavController,
@@ -79,7 +82,8 @@ class DefaultBrowserToolbarMenuController(
private val tabCollectionStorage: TabCollectionStorage,
private val topSitesStorage: DefaultTopSitesStorage,
private val pinnedSiteStorage: PinnedSiteStorage,
- private val browserStore: BrowserStore,
+ private val onShowPinVerification: (Intent) -> Unit,
+ private val onBiometricAuthenticationSuccessful: () -> Unit,
) : BrowserToolbarMenuController {
private val currentSession
@@ -214,11 +218,15 @@ class DefaultBrowserToolbarMenuController(
}
}
is ToolbarMenu.Item.Share -> {
+ val sessionId = currentSession?.id
+ val url = sessionId?.let {
+ store.state.findTab(it)?.getUrl()
+ }
val directions = NavGraphDirections.actionGlobalShareFragment(
- sessionId = currentSession?.id,
+ sessionId = sessionId,
data = arrayOf(
ShareData(
- url = getProperUrl(currentSession),
+ url = url,
title = currentSession?.content?.title,
),
),
@@ -257,9 +265,9 @@ class DefaultBrowserToolbarMenuController(
}
}
is ToolbarMenu.Item.OpenInRegularTab -> {
- currentSession?.let { session ->
- getProperUrl(session)?.let { url ->
- tabsUseCases.migratePrivateTabUseCase.invoke(session.id, url)
+ currentSession?.id?.let { sessionId ->
+ store.state.findTab(sessionId)?.getUrl()?.let { url ->
+ tabsUseCases.migratePrivateTabUseCase.invoke(sessionId, url)
}
}
}
@@ -350,7 +358,7 @@ class DefaultBrowserToolbarMenuController(
}
is ToolbarMenu.Item.Bookmark -> {
store.state.selectedTab?.let {
- getProperUrl(it)?.let { url -> bookmarkTapped(url, it.content.title) }
+ it.getUrl()?.let { url -> bookmarkTapped(url, it.content.title) }
}
}
is ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically {
@@ -365,7 +373,15 @@ class DefaultBrowserToolbarMenuController(
BrowserFragmentDirections.actionGlobalHistoryFragment(),
)
}
-
+ is ToolbarMenu.Item.Passwords -> browserAnimator.captureEngineViewAndDrawStatically {
+ fragment.view?.let { view ->
+ bindBiometricsCredentialsPromptOrShowWarning(
+ view = view,
+ onShowPinVerification = onShowPinVerification,
+ onAuthSuccess = onBiometricAuthenticationSuccessful,
+ )
+ }
+ }
is ToolbarMenu.Item.Downloads -> browserAnimator.captureEngineViewAndDrawStatically {
navController.nav(
R.id.browserFragment,
@@ -411,25 +427,12 @@ class DefaultBrowserToolbarMenuController(
ToolbarMenu.Item.Translate -> {
Translations.action.record(Translations.ActionExtra("main_flow_browser"))
val directions =
- BrowserFragmentDirections.actionBrowserFragmentToTranslationsDialogFragment(
- sessionId = currentSession?.id,
- )
+ BrowserFragmentDirections.actionBrowserFragmentToTranslationsDialogFragment()
navController.navigateSafe(R.id.browserFragment, directions)
}
}
}
- private fun getProperUrl(currentSession: SessionState?): String? {
- return currentSession?.id?.let {
- val currentTab = browserStore.state.findTab(it)
- if (currentTab?.readerState?.active == true) {
- currentTab.readerState.activeUrl
- } else {
- currentSession.content.url
- }
- }
- }
-
@Suppress("ComplexMethod", "LongMethod")
private fun trackToolbarItemInteraction(item: ToolbarMenu.Item) {
when (item) {
@@ -494,6 +497,8 @@ class DefaultBrowserToolbarMenuController(
Events.browserMenuAction.record(Events.BrowserMenuActionExtra("bookmarks"))
is ToolbarMenu.Item.History ->
Events.browserMenuAction.record(Events.BrowserMenuActionExtra("history"))
+ is ToolbarMenu.Item.Passwords ->
+ Events.browserMenuAction.record(Events.BrowserMenuActionExtra("passwords"))
is ToolbarMenu.Item.Downloads ->
Events.browserMenuAction.record(Events.BrowserMenuActionExtra("downloads"))
is ToolbarMenu.Item.NewTab ->
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt
index 2c93538953..199bfb3bcc 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt
@@ -6,6 +6,7 @@ package org.mozilla.fenix.components.toolbar
import android.content.Context
import android.graphics.Color
+import android.net.Uri
import android.view.HapticFeedbackConstants
import android.view.LayoutInflater
import android.view.View
@@ -29,6 +30,7 @@ import mozilla.components.concept.toolbar.ScrollableToolbar
import mozilla.components.support.ktx.util.URLStringUtils
import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.toolbar.interactor.BrowserToolbarInteractor
import org.mozilla.fenix.customtabs.CustomTabToolbarIntegration
import org.mozilla.fenix.customtabs.CustomTabToolbarMenu
@@ -43,7 +45,7 @@ import mozilla.components.ui.widgets.behavior.ViewPosition as MozacToolbarPositi
@SuppressWarnings("LargeClass", "LongParameterList")
class BrowserToolbarView(
- context: Context,
+ private val context: Context,
container: ViewGroup,
private val settings: Settings,
private val interactor: BrowserToolbarInteractor,
@@ -70,6 +72,8 @@ class BrowserToolbarView(
private val tabStripView: ComposeView by lazy { layout.findViewById(R.id.tabStripView) }
+ private val isNavBarEnabled = IncompleteRedesignToolbarFeature(context.settings()).isEnabled
+
val toolbarIntegration: ToolbarIntegration
val menuToolbar: ToolbarMenu
@@ -101,9 +105,11 @@ class BrowserToolbarView(
true
}
+ view.isNavBarEnabled = isNavBarEnabled
+
with(context) {
val isPinningSupported = components.useCases.webAppUseCases.isPinningSupported()
- val searchUrlBackground = if (IncompleteRedesignToolbarFeature(context.settings()).isEnabled) {
+ val searchUrlBackground = if (isNavBarEnabled) {
R.drawable.search_url_background
} else {
R.drawable.search_old_url_background
@@ -150,7 +156,13 @@ class BrowserToolbarView(
ThemeManager.resolveAttribute(R.attr.borderToolbarDivider, context),
)
- display.urlFormatter = { url -> URLStringUtils.toDisplayUrl(url) }
+ display.urlFormatter = { url ->
+ if (isNavBarEnabled) {
+ Uri.parse(url.toString()).host ?: url
+ } else {
+ URLStringUtils.toDisplayUrl(url)
+ }
+ }
display.colors = display.colors.copy(
text = primaryTextColor,
@@ -211,8 +223,6 @@ class BrowserToolbarView(
isPrivate = customTabSession.content.private,
)
} else {
- val isNavBarEnabled = IncompleteRedesignToolbarFeature(context.settings()).isEnabled
-
DefaultToolbarIntegration(
this,
view,
@@ -322,5 +332,5 @@ class BrowserToolbarView(
}
private fun shouldShowTabStrip() =
- customTabSession == null && settings.isTabletAndTabStripEnabled
+ customTabSession == null && context.isTabStripEnabled()
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt
index 6e28294734..0af1430417 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt
@@ -232,6 +232,14 @@ open class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.Downloads)
}
+ private val passwordsItem = BrowserMenuImageText(
+ context.getString(R.string.preferences_sync_logins_2),
+ R.drawable.mozac_ic_login_24,
+ primaryTextColor(),
+ ) {
+ onItemTapped.invoke(ToolbarMenu.Item.Passwords)
+ }
+
private val extensionsItem = WebExtensionPlaceholderMenuItem(
id = WebExtensionPlaceholderMenuItem.MAIN_EXTENSIONS_MENU_ID,
)
@@ -409,6 +417,7 @@ open class DefaultToolbarMenu(
bookmarksItem,
historyItem,
downloadsItem,
+ passwordsItem,
extensionsItem,
syncMenuItem(),
BrowserMenuDivider(),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt
index 179d30db5c..ebffb04909 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt
@@ -48,6 +48,11 @@ interface ToolbarMenu {
object CustomizeReaderView : Item()
object Bookmarks : Item()
object History : Item()
+
+ /**
+ * The Passwords menu item
+ */
+ object Passwords : Item()
object Downloads : Item()
object NewTab : Item()
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/DismissibleItemBackground.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/DismissibleItemBackground.kt
index a4ad6da918..98448f626b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/DismissibleItemBackground.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/DismissibleItemBackground.kt
@@ -59,7 +59,7 @@ fun DismissibleItemBackground(
Alignment.CenterStart
},
),
- tint = FirefoxTheme.colors.iconWarning,
+ tint = FirefoxTheme.colors.iconCritical,
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt
index 2cc4421ac7..ad65c37d17 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/Button.kt
@@ -232,7 +232,7 @@ fun DestructiveButton(
text: String,
modifier: Modifier = Modifier.fillMaxWidth(),
enabled: Boolean = true,
- textColor: Color = FirefoxTheme.colors.textWarningButton,
+ textColor: Color = FirefoxTheme.colors.textCriticalButton,
backgroundColor: Color = FirefoxTheme.colors.actionSecondary,
icon: Painter? = null,
iconModifier: Modifier = Modifier,
@@ -246,7 +246,7 @@ fun DestructiveButton(
enabled = enabled,
icon = icon,
iconModifier = iconModifier,
- tint = FirefoxTheme.colors.iconWarningButton,
+ tint = FirefoxTheme.colors.iconCriticalButton,
onClick = onClick,
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt
index 018b6722ba..0d09bc6a22 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/button/TextButton.kt
@@ -5,7 +5,7 @@
package org.mozilla.fenix.compose.button
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@@ -20,6 +20,8 @@ import java.util.Locale
* @param text The button text to be displayed.
* @param onClick Invoked when the user clicks on the button.
* @param modifier [Modifier] Used to shape and position the underlying [androidx.compose.material.TextButton].
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable.
* @param textColor [Color] to apply to the button text.
* @param upperCaseText If the button text should be in uppercase letters.
*/
@@ -28,12 +30,14 @@ fun TextButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
+ enabled: Boolean = true,
textColor: Color = FirefoxTheme.colors.textAccent,
upperCaseText: Boolean = true,
) {
androidx.compose.material.TextButton(
onClick = onClick,
modifier = modifier,
+ enabled = enabled,
) {
Text(
text = if (upperCaseText) {
@@ -41,7 +45,7 @@ fun TextButton(
} else {
text
},
- color = textColor,
+ color = if (enabled) textColor else FirefoxTheme.colors.textDisabled,
style = FirefoxTheme.typography.button,
maxLines = 1,
)
@@ -52,11 +56,17 @@ fun TextButton(
@LightDarkPreview
private fun TextButtonPreview() {
FirefoxTheme {
- Box(Modifier.background(FirefoxTheme.colors.layer1)) {
+ Column(Modifier.background(FirefoxTheme.colors.layer1)) {
TextButton(
text = "label",
onClick = {},
)
+
+ TextButton(
+ text = "disabled",
+ onClick = {},
+ enabled = false,
+ )
}
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/list/ListItem.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/list/ListItem.kt
index 0a8e88b1ea..48c6e903b2 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/list/ListItem.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/list/ListItem.kt
@@ -23,6 +23,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.Role
@@ -36,6 +37,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.Favicon
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.button.RadioButton
+import org.mozilla.fenix.compose.button.TextButton
import org.mozilla.fenix.theme.FirefoxTheme
private val LIST_ITEM_HEIGHT = 56.dp
@@ -43,8 +45,8 @@ private val LIST_ITEM_HEIGHT = 56.dp
private val ICON_SIZE = 24.dp
/**
- * List item used to display a label with an optional description text and
- * an optional [IconButton] at the end.
+ * List item used to display a label with an optional description text and an optional
+ * [IconButton] or [Icon] at the end.
*
* @param label The label in the list item.
* @param modifier [Modifier] to be applied to the layout.
@@ -52,9 +54,11 @@ private val ICON_SIZE = 24.dp
* @param description An optional description text below the label.
* @param maxDescriptionLines An optional maximum number of lines for the description text to span.
* @param onClick Called when the user clicks on the item.
- * @param iconPainter [Painter] used to display an [IconButton] after the list item.
+ * @param iconPainter [Painter] used to display an icon after the list item.
* @param iconDescription Content description of the icon.
- * @param onIconClick Called when the user clicks on the icon.
+ * @param iconTint Tint applied to [iconPainter].
+ * @param onIconClick Called when the user clicks on the icon. An [IconButton] will be
+ * displayed if this is provided. Otherwise, an [Icon] will be displayed.
*/
@Composable
fun TextListItem(
@@ -66,6 +70,7 @@ fun TextListItem(
onClick: (() -> Unit)? = null,
iconPainter: Painter? = null,
iconDescription: String? = null,
+ iconTint: Color = FirefoxTheme.colors.iconPrimary,
onIconClick: (() -> Unit)? = null,
) {
ListItem(
@@ -87,9 +92,16 @@ fun TextListItem(
Icon(
painter = iconPainter,
contentDescription = iconDescription,
- tint = FirefoxTheme.colors.iconPrimary,
+ tint = iconTint,
)
}
+ } else if (iconPainter != null) {
+ Icon(
+ painter = iconPainter,
+ contentDescription = iconDescription,
+ modifier = Modifier.padding(end = 16.dp),
+ tint = iconTint,
+ )
}
}
}
@@ -160,54 +172,135 @@ fun FaviconListItem(
/**
* List item used to display a label and an icon at the beginning with an optional description
- * text and an optional [IconButton] at the end.
+ * text and an optional [IconButton] or [Icon] at the end.
*
* @param label The label in the list item.
+ * @param labelTextColor [Color] to be applied to the label.
* @param description An optional description text below the label.
+ * @param enabled Controls the enabled state of the list item. When `false`, the list item will not
+ * be clickable.
* @param onClick Called when the user clicks on the item.
* @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
* @param beforeIconDescription Content description of the icon.
- * @param afterIconPainter [Painter] used to display an [IconButton] after the list item.
+ * @param beforeIconTint Tint applied to [beforeIconPainter].
+ * @param afterIconPainter [Painter] used to display an icon after the list item.
* @param afterIconDescription Content description of the icon.
- * @param onAfterIconClick Called when the user clicks on the icon.
+ * @param afterIconTint Tint applied to [afterIconPainter].
+ * @param onAfterIconClick Called when the user clicks on the icon. An [IconButton] will be
+ * displayed if this is provided. Otherwise, an [Icon] will be displayed.
*/
@Composable
fun IconListItem(
label: String,
+ labelTextColor: Color = FirefoxTheme.colors.textPrimary,
description: String? = null,
+ enabled: Boolean = true,
onClick: (() -> Unit)? = null,
beforeIconPainter: Painter,
beforeIconDescription: String? = null,
+ beforeIconTint: Color = FirefoxTheme.colors.iconPrimary,
afterIconPainter: Painter? = null,
afterIconDescription: String? = null,
+ afterIconTint: Color = FirefoxTheme.colors.iconPrimary,
onAfterIconClick: (() -> Unit)? = null,
) {
ListItem(
label = label,
+ labelTextColor = labelTextColor,
description = description,
+ enabled = enabled,
onClick = onClick,
beforeListAction = {
Icon(
painter = beforeIconPainter,
contentDescription = beforeIconDescription,
modifier = Modifier.padding(horizontal = 16.dp),
- tint = FirefoxTheme.colors.iconPrimary,
+ tint = if (enabled) beforeIconTint else FirefoxTheme.colors.iconDisabled,
)
},
afterListAction = {
+ val tint = if (enabled) afterIconTint else FirefoxTheme.colors.iconDisabled
+
if (afterIconPainter != null && onAfterIconClick != null) {
IconButton(
onClick = onAfterIconClick,
modifier = Modifier
.padding(end = 16.dp)
.size(ICON_SIZE),
+ enabled = enabled,
) {
Icon(
painter = afterIconPainter,
contentDescription = afterIconDescription,
- tint = FirefoxTheme.colors.iconPrimary,
+ tint = tint,
)
}
+ } else if (afterIconPainter != null) {
+ Icon(
+ painter = afterIconPainter,
+ contentDescription = afterIconDescription,
+ modifier = Modifier.padding(end = 16.dp),
+ tint = tint,
+ )
+ }
+ },
+ )
+}
+
+/**
+ * List item used to display a label and an icon at the beginning with an optional description
+ * text and an optional [TextButton] at the end.
+ *
+ * @param label The label in the list item.
+ * @param labelTextColor [Color] to be applied to the label.
+ * @param description An optional description text below the label.
+ * @param enabled Controls the enabled state of the list item. When `false`, the list item will not
+ * be clickable.
+ * @param onClick Called when the user clicks on the item.
+ * @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
+ * @param beforeIconDescription Content description of the icon.
+ * @param beforeIconTint Tint applied to [beforeIconPainter].
+ * @param afterButtonText The button text to be displayed after the list item.
+ * @param afterButtonTextColor [Color] to apply to [afterButtonText].
+ * @param onAfterButtonClick Called when the user clicks on the text button.
+ */
+@Composable
+fun IconListItem(
+ label: String,
+ labelTextColor: Color = FirefoxTheme.colors.textPrimary,
+ description: String? = null,
+ enabled: Boolean = true,
+ onClick: (() -> Unit)? = null,
+ beforeIconPainter: Painter,
+ beforeIconDescription: String? = null,
+ beforeIconTint: Color = FirefoxTheme.colors.iconPrimary,
+ afterButtonText: String? = null,
+ afterButtonTextColor: Color = FirefoxTheme.colors.actionPrimary,
+ onAfterButtonClick: (() -> Unit)? = null,
+) {
+ ListItem(
+ label = label,
+ labelTextColor = labelTextColor,
+ description = description,
+ enabled = enabled,
+ onClick = onClick,
+ beforeListAction = {
+ Icon(
+ painter = beforeIconPainter,
+ contentDescription = beforeIconDescription,
+ modifier = Modifier.padding(horizontal = 16.dp),
+ tint = if (enabled) beforeIconTint else FirefoxTheme.colors.iconDisabled,
+ )
+ },
+ afterListAction = {
+ if (afterButtonText != null && onAfterButtonClick != null) {
+ TextButton(
+ text = afterButtonText,
+ onClick = onAfterButtonClick,
+ enabled = enabled,
+ textColor = afterButtonTextColor,
+ upperCaseText = false,
+ )
}
},
)
@@ -270,9 +363,12 @@ fun RadioButtonListItem(
*
* @param label The label in the list item.
* @param modifier [Modifier] to be applied to the layout.
+ * @param labelTextColor [Color] to be applied to the label.
* @param maxLabelLines An optional maximum number of lines for the label text to span.
* @param description An optional description text below the label.
* @param maxDescriptionLines An optional maximum number of lines for the description text to span.
+ * @param enabled Controls the enabled state of the list item. When `false`, the list item will not
+ * be clickable.
* @param onClick Called when the user clicks on the item.
* @param beforeListAction Optional Composable for adding UI before the list item.
* @param afterListAction Optional Composable for adding UI to the end of the list item.
@@ -281,16 +377,18 @@ fun RadioButtonListItem(
private fun ListItem(
label: String,
modifier: Modifier = Modifier,
+ labelTextColor: Color = FirefoxTheme.colors.textPrimary,
maxLabelLines: Int = 1,
description: String? = null,
maxDescriptionLines: Int = 1,
+ enabled: Boolean = true,
onClick: (() -> Unit)? = null,
beforeListAction: @Composable RowScope.() -> Unit = {},
afterListAction: @Composable RowScope.() -> Unit = {},
) {
Row(
modifier = when (onClick != null) {
- true -> Modifier.clickable { onClick() }
+ true -> Modifier.clickable(enabled = enabled) { onClick() }
false -> Modifier
}.then(
Modifier.defaultMinSize(minHeight = LIST_ITEM_HEIGHT),
@@ -306,7 +404,7 @@ private fun ListItem(
) {
Text(
text = label,
- color = FirefoxTheme.colors.textPrimary,
+ color = if (enabled) labelTextColor else FirefoxTheme.colors.textDisabled,
style = FirefoxTheme.typography.subtitle1,
maxLines = maxLabelLines,
)
@@ -314,7 +412,7 @@ private fun ListItem(
description?.let {
Text(
text = description,
- color = FirefoxTheme.colors.textSecondary,
+ color = if (enabled) FirefoxTheme.colors.textSecondary else FirefoxTheme.colors.textDisabled,
style = FirefoxTheme.typography.body2,
maxLines = maxDescriptionLines,
)
@@ -352,13 +450,21 @@ private fun TextListItemWithDescriptionPreview() {
@Preview(name = "TextListItem with a right icon", uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun TextListItemWithIconPreview() {
FirefoxTheme {
- Box(Modifier.background(FirefoxTheme.colors.layer1)) {
+ Column(Modifier.background(FirefoxTheme.colors.layer1)) {
TextListItem(
- label = "Label + right icon",
- iconPainter = painterResource(R.drawable.ic_menu),
+ label = "Label + right icon button",
+ onClick = {},
+ iconPainter = painterResource(R.drawable.mozac_ic_folder_24),
iconDescription = "click me",
onIconClick = { println("icon click") },
)
+
+ TextListItem(
+ label = "Label + right icon",
+ onClick = {},
+ iconPainter = painterResource(R.drawable.mozac_ic_folder_24),
+ iconDescription = "click me",
+ )
}
}
}
@@ -367,11 +473,40 @@ private fun TextListItemWithIconPreview() {
@Preview(name = "IconListItem", uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun IconListItemPreview() {
FirefoxTheme {
- Box(Modifier.background(FirefoxTheme.colors.layer1)) {
+ Column(Modifier.background(FirefoxTheme.colors.layer1)) {
+ IconListItem(
+ label = "Left icon list item",
+ onClick = {},
+ beforeIconPainter = painterResource(R.drawable.mozac_ic_folder_24),
+ beforeIconDescription = "click me",
+ )
+
IconListItem(
label = "Left icon list item",
- beforeIconPainter = painterResource(R.drawable.ic_folder_icon),
+ labelTextColor = FirefoxTheme.colors.textAccent,
+ onClick = {},
+ beforeIconPainter = painterResource(R.drawable.mozac_ic_folder_24),
+ beforeIconDescription = "click me",
+ beforeIconTint = FirefoxTheme.colors.iconAccentViolet,
+ )
+
+ IconListItem(
+ label = "Left icon list item + right icon",
+ onClick = {},
+ beforeIconPainter = painterResource(R.drawable.mozac_ic_folder_24),
beforeIconDescription = "click me",
+ afterIconPainter = painterResource(R.drawable.mozac_ic_chevron_right_24),
+ afterIconDescription = null,
+ )
+
+ IconListItem(
+ label = "Left icon list item + right icon (disabled)",
+ enabled = false,
+ onClick = {},
+ beforeIconPainter = painterResource(R.drawable.mozac_ic_folder_24),
+ beforeIconDescription = "click me",
+ afterIconPainter = painterResource(R.drawable.mozac_ic_chevron_right_24),
+ afterIconDescription = null,
)
}
}
@@ -379,20 +514,29 @@ private fun IconListItemPreview() {
@Composable
@Preview(
- name = "IconListItem with an interactable right icon",
+ name = "IconListItem with after list action",
uiMode = Configuration.UI_MODE_NIGHT_YES,
)
-private fun IconListItemWithRightIconPreview() {
+private fun IconListItemWithAfterListActionPreview() {
FirefoxTheme {
- Box(Modifier.background(FirefoxTheme.colors.layer1)) {
+ Column(Modifier.background(FirefoxTheme.colors.layer1)) {
IconListItem(
- label = "Left icon list item + right icon",
- beforeIconPainter = painterResource(R.drawable.ic_folder_icon),
+ label = "IconListItem + right icon + clicks",
+ beforeIconPainter = painterResource(R.drawable.mozac_ic_folder_24),
beforeIconDescription = null,
- afterIconPainter = painterResource(R.drawable.ic_menu),
+ afterIconPainter = painterResource(R.drawable.mozac_ic_ellipsis_vertical_24),
afterIconDescription = "click me",
onAfterIconClick = { println("icon click") },
)
+
+ IconListItem(
+ label = "IconListItem + text button",
+ onClick = { println("list item click") },
+ beforeIconPainter = painterResource(R.drawable.mozac_ic_folder_24),
+ beforeIconDescription = "click me",
+ afterButtonText = "Edit",
+ onAfterButtonClick = { println("text button click") },
+ )
}
}
}
@@ -410,14 +554,14 @@ private fun FaviconListItemPreview() {
description = "Description text",
onClick = { println("list item click") },
url = "",
- iconPainter = painterResource(R.drawable.ic_menu),
+ iconPainter = painterResource(R.drawable.mozac_ic_ellipsis_vertical_24),
onIconClick = { println("icon click") },
)
FaviconListItem(
label = "Favicon + painter",
description = "Description text",
- faviconPainter = painterResource(id = R.drawable.ic_tab_collection),
+ faviconPainter = painterResource(id = R.drawable.mozac_ic_collection_24),
onClick = { println("list item click") },
url = "",
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/DismissedTabBackground.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/DismissedTabBackground.kt
index 802457d4f8..3b40e3278a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/DismissedTabBackground.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/DismissedTabBackground.kt
@@ -60,7 +60,7 @@ fun DismissedTabBackground(
.alpha(
if (dismissDirection == DismissDirection.StartToEnd || dismissDirection == null) 1f else 0f,
),
- tint = FirefoxTheme.colors.iconWarning,
+ tint = FirefoxTheme.colors.iconCritical,
)
Icon(
@@ -72,7 +72,7 @@ fun DismissedTabBackground(
.alpha(
if (dismissDirection == DismissDirection.EndToStart || dismissDirection == null) 1f else 0f,
),
- tint = FirefoxTheme.colors.iconWarning,
+ tint = FirefoxTheme.colors.iconCritical,
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt
index 0f1fff66bd..6c3abb3b0c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt
@@ -34,6 +34,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BaseBrowserFragment
import org.mozilla.fenix.browser.CustomTabContextMenuCandidate
import org.mozilla.fenix.browser.FenixSnackbarDelegate
+import org.mozilla.fenix.components.menu.MenuAccessPoint
import org.mozilla.fenix.components.toolbar.IncompleteRedesignToolbarFeature
import org.mozilla.fenix.components.toolbar.ToolbarMenu
import org.mozilla.fenix.components.toolbar.ToolbarPosition
@@ -130,8 +131,9 @@ class ExternalAppBrowserFragment : BaseBrowserFragment() {
onMenuButtonClick = {
nav(
R.id.externalAppBrowserFragment,
- ExternalAppBrowserFragmentDirections
- .actionGlobalMenuDialogFragment(),
+ ExternalAppBrowserFragmentDirections.actionGlobalMenuDialogFragment(
+ accesspoint = MenuAccessPoint.External,
+ ),
)
},
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt
index 5fa97b7c03..54ca60feaf 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt
@@ -14,8 +14,10 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.TextFieldDefaults
@@ -116,7 +118,8 @@ private fun TabToolsContent(
Column(
modifier = Modifier
.fillMaxSize()
- .padding(all = 16.dp),
+ .padding(all = 16.dp)
+ .verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
TabCounter(
@@ -152,7 +155,7 @@ private fun TabCounter(
Spacer(modifier = Modifier.height(16.dp))
TabCountRow(
- tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_normal),
+ tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_active),
count = activeTabCount,
)
@@ -254,10 +257,10 @@ private fun TabCreationTool(
textColor = FirefoxTheme.colors.textPrimary,
backgroundColor = Color.Transparent,
cursorColor = FirefoxTheme.colors.borderFormDefault,
- errorCursorColor = FirefoxTheme.colors.borderWarning,
+ errorCursorColor = FirefoxTheme.colors.borderCritical,
focusedIndicatorColor = FirefoxTheme.colors.borderPrimary,
unfocusedIndicatorColor = FirefoxTheme.colors.borderPrimary,
- errorIndicatorColor = FirefoxTheme.colors.borderWarning,
+ errorIndicatorColor = FirefoxTheme.colors.borderCritical,
),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/DebugOverlay.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/DebugOverlay.kt
index fa1959cd79..92e41355c0 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/DebugOverlay.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/DebugOverlay.kt
@@ -26,6 +26,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
@@ -88,6 +89,7 @@ fun DebugOverlay(
onClick = {
onDrawerOpen()
},
+ contentDescription = stringResource(R.string.debug_drawer_fab_content_description),
)
// ModalDrawer utilizes a Surface, which blocks ALL clicks behind it, preventing the app
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/StartDownloadDialog.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/StartDownloadDialog.kt
index 6ed2c57fb5..96d07d5276 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/StartDownloadDialog.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/StartDownloadDialog.kt
@@ -17,7 +17,6 @@ import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import androidx.annotation.VisibleForTesting
import androidx.coordinatorlayout.widget.CoordinatorLayout
-import androidx.core.view.ViewCompat
import androidx.core.view.children
import androidx.viewbinding.ViewBinding
import mozilla.components.concept.base.crash.Breadcrumb
@@ -124,10 +123,7 @@ abstract class StartDownloadDialog(
parent?.children
?.filterNot { it.id == R.id.startDownloadDialogContainer }
?.forEach {
- ViewCompat.setImportantForAccessibility(
- it,
- ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES,
- )
+ it.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES)
}
}
@@ -136,10 +132,7 @@ abstract class StartDownloadDialog(
parent?.children
?.filterNot { it.id == R.id.startDownloadDialogContainer }
?.forEach {
- ViewCompat.setImportantForAccessibility(
- it,
- ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS,
- )
+ it.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt
index bb927596a4..d0423728d4 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Activity.kt
@@ -146,6 +146,27 @@ fun Activity.openSetDefaultBrowserOption(
}
}
+/**
+ * Checks if the app can prompt the user to set it as the default browser.
+ *
+ * From Android 10, a new method to prompt the user to set default apps has been introduced.
+ * This method checks if the app can prompt the user to set it as the default browser
+ * based on the Android version and the availability of the ROLE_BROWSER.
+ */
+fun Activity.isDefaultBrowserPromptSupported(): Boolean {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ getSystemService(RoleManager::class.java).also {
+ if (it.isRoleAvailable(RoleManager.ROLE_BROWSER) && !it.isRoleHeld(
+ RoleManager.ROLE_BROWSER,
+ )
+ ) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
@RequiresApi(Build.VERSION_CODES.N)
private fun Activity.navigateToDefaultBrowserAppsSettings(
from: BrowserDirection,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/AppState.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/AppState.kt
index d0491be7f0..db191ed0d1 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/AppState.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/AppState.kt
@@ -170,7 +170,7 @@ internal fun getFilteredSponsoredStories(
fun AppState.filterState(blocklistHandler: BlocklistHandler): AppState =
with(blocklistHandler) {
copy(
- recentBookmarks = recentBookmarks.filteredByBlocklist(),
+ bookmarks = bookmarks.filteredByBlocklist(),
recentTabs = recentTabs.filteredByBlocklist().filterContile(),
recentHistory = recentHistory.filteredByBlocklist().filterContile(),
recentSyncedTabState = recentSyncedTabState.filteredByBlocklist().filterContile(),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Bitmap.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Bitmap.kt
index 02f63839f6..5e02e68873 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Bitmap.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Bitmap.kt
@@ -8,6 +8,7 @@ import android.graphics.Bitmap
import android.graphics.Matrix
import android.view.View
import android.widget.ImageView
+import androidx.annotation.VisibleForTesting
/**
* This will scale the received [Bitmap] to the size of the [view]. It retains the bitmap's
@@ -33,8 +34,8 @@ fun Bitmap.scaleToBottomOfView(view: ImageView) {
oldRight: Int,
oldBottom: Int,
) {
- val viewWidth: Float = view.width.toFloat()
- val viewHeight: Float = view.height.toFloat()
+ val viewWidth = view.width.toFloat()
+ val viewHeight = view.safeHeight().toFloat()
val bitmapWidth = bitmap.width
val bitmapHeight = bitmap.height
val widthScale = viewWidth / bitmapWidth
@@ -52,3 +53,16 @@ fun Bitmap.scaleToBottomOfView(view: ImageView) {
},
)
}
+
+/**
+ * If the keyboard is open we must factor in the height for the correct view height.
+ */
+@VisibleForTesting
+internal fun View.safeHeight(): Int {
+ val keyboardHeight = getKeyboardHeight()
+ return if (keyboardHeight > 0) {
+ keyboardHeight.plus(height)
+ } else {
+ height
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Context.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Context.kt
index 11f37595d8..a4432ba37a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Context.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Context.kt
@@ -145,3 +145,9 @@ fun Context.tabClosedUndoMessage(private: Boolean): String =
} else {
getString(R.string.snackbar_tab_closed)
}
+
+/**
+ * Returns true if the device is a tablet
+ */
+fun Context.isTablet(): Boolean =
+ resources.getBoolean(R.bool.tablet)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt
index 0bbc0ee729..db7f36cc40 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt
@@ -6,6 +6,8 @@ package org.mozilla.fenix.ext
import android.app.Activity
import android.content.Intent
+import android.view.View
+import android.view.ViewGroup
import android.view.WindowManager
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
@@ -18,9 +20,12 @@ import androidx.navigation.NavDirections
import androidx.navigation.NavOptions
import androidx.navigation.fragment.findNavController
import mozilla.components.concept.base.crash.Breadcrumb
+import mozilla.components.support.utils.ext.isLandscape
import org.mozilla.fenix.NavHostActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.Components
+import org.mozilla.fenix.components.toolbar.ToolbarPosition
+import org.mozilla.fenix.components.toolbar.navbar.ToolbarContainerView
/**
* Get the requireComponents of this application.
@@ -149,3 +154,53 @@ fun Fragment.registerForActivityResult(
}
}
}
+
+/**
+ * Checks whether the current fragment is running on a tablet.
+ */
+fun Fragment.isTablet(): Boolean {
+ return resources.getBoolean(R.bool.tablet)
+}
+
+/**
+ *
+ * Manages the state of the NavBar upon an orientation change.
+ *
+ * @param parent The top level [ViewGroup] of the fragment, which will be hosting toolbar/navbar container.
+ * @param toolbarView [View] responsible for showing the AddressBar.
+ * @param bottomToolbarContainerView The [ToolbarContainerView] hosting the NavBar.
+ * @param reinitializeNavBar lambda for re-initializing the NavBar inside the host [Fragment].
+ */
+fun Fragment.updateNavBarForConfigurationChange(
+ parent: ViewGroup,
+ toolbarView: View,
+ bottomToolbarContainerView: ToolbarContainerView?,
+ reinitializeNavBar: () -> Unit,
+) {
+ if (requireContext().isLandscape()) {
+ // In landscape mode we want to remove the navigation bar.
+ parent.removeView(bottomToolbarContainerView)
+
+ // If address bar was positioned at bottom and we have removed the toolbar container, we are adding address bar
+ // back.
+ val isToolbarAtBottom = requireComponents.settings.toolbarPosition == ToolbarPosition.BOTTOM
+
+ // Toolbar already having a parent is an edge case, but it could happen if configurationChange is called after
+ // onCreateView with the same orientation. Caught it on a foldable emulator while going from single screen
+ // portrait mode to landscape table, back and forth.
+ val hasParent = toolbarView.parent != null
+ if (isToolbarAtBottom && !hasParent) {
+ parent.addView(toolbarView)
+ }
+ } else {
+ // Already having a bottomContainer after switching back to portrait mode will happen when address bar is
+ // positioned at bottom and also as an edge case if configurationChange is called after onCreateView with the
+ // same orientation. Caught it on a foldable emulator while going from single screen portrait mode to landscape
+ // table, back and forth.
+ bottomToolbarContainerView?.let {
+ parent.removeView(it)
+ }
+
+ reinitializeNavBar()
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/View.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/View.kt
index 3c5976e428..9f2d2e0035 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/View.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/View.kt
@@ -2,18 +2,16 @@
* 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/. */
-@file:Suppress("TooManyFunctions")
-
package org.mozilla.fenix.ext
import android.graphics.Rect
import android.os.Build
import android.view.TouchDelegate
import android.view.View
-import android.view.accessibility.AccessibilityNodeInfo
import androidx.annotation.Dimension
import androidx.annotation.Dimension.Companion.DP
import androidx.annotation.VisibleForTesting
+import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import mozilla.components.support.ktx.android.util.dpToPx
import mozilla.components.support.utils.ext.bottom
@@ -54,98 +52,12 @@ fun View.removeTouchDelegate() {
}
}
-/**
- * Sets the new a11y parent.
- */
-fun View.setNewAccessibilityParent(newParent: View) {
- this.accessibilityDelegate = object : View.AccessibilityDelegate() {
- override fun onInitializeAccessibilityNodeInfo(
- host: View,
- info: AccessibilityNodeInfo,
- ) {
- super.onInitializeAccessibilityNodeInfo(host, info)
- info.setParent(newParent)
- }
- }
-}
-
-/**
- * Updates the a11y collection item info for an item in a list.
- */
-fun View.updateAccessibilityCollectionItemInfo(
- rowIndex: Int,
- columnIndex: Int,
- isSelected: Boolean,
- rowSpan: Int = 1,
- columnSpan: Int = 1,
-) {
- this.accessibilityDelegate = object : View.AccessibilityDelegate() {
- override fun onInitializeAccessibilityNodeInfo(
- host: View,
- info: AccessibilityNodeInfo,
- ) {
- super.onInitializeAccessibilityNodeInfo(host, info)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- info.collectionItemInfo =
- AccessibilityNodeInfo.CollectionItemInfo(
- rowIndex,
- rowSpan,
- columnIndex,
- columnSpan,
- false,
- isSelected,
- )
- } else {
- @Suppress("DEPRECATION")
- AccessibilityNodeInfo.CollectionItemInfo.obtain(
- rowIndex,
- rowSpan,
- columnIndex,
- columnSpan,
- false,
- isSelected,
- )
- }
- }
- }
-}
-
-/**
- * Updates the a11y collection info for a list.
- */
-fun View.updateAccessibilityCollectionInfo(
- rowCount: Int,
- columnCount: Int,
-) {
- this.accessibilityDelegate = object : View.AccessibilityDelegate() {
- override fun onInitializeAccessibilityNodeInfo(
- host: View,
- info: AccessibilityNodeInfo,
- ) {
- super.onInitializeAccessibilityNodeInfo(host, info)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- info.collectionInfo = AccessibilityNodeInfo.CollectionInfo(
- rowCount,
- columnCount,
- false,
- )
- } else {
- @Suppress("DEPRECATION")
- info.collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
- rowCount,
- columnCount,
- false,
- )
- }
- }
- }
-}
-
/**
* Fills a [Rect] with data about a view's location in the screen.
*
- * @see View.getLocationOnScreen
- * @see View.getRectWithViewLocation for a version of this that is relative to a window
+ * @see android.view.View.getLocationOnScreen
+ * @see mozilla.components.support.ktx.android.view.getRectWithViewLocation for a version of this
+ * that is relative to a window
*/
fun View.getRectWithScreenLocation(): Rect {
val locationOnScreen = IntArray(2).apply { getLocationOnScreen(this) }
@@ -196,8 +108,10 @@ internal fun View.getWindowVisibleDisplayFrame(): Rect = with(Rect()) {
this
}
-@VisibleForTesting
-internal fun View.getKeyboardHeight(): Int {
+/**
+ * Calculates the height of the onscreen keyboard.
+ */
+fun View.getKeyboardHeight(): Int {
val windowRect = getWindowVisibleDisplayFrame()
val statusBarHeight = windowRect.top
var keyboardHeight = rootView.height - (windowRect.height() + statusBarHeight)
@@ -207,10 +121,3 @@ internal fun View.getKeyboardHeight(): Int {
return keyboardHeight
}
-
-/**
- * The assumed minimum height of the keyboard.
- */
-@VisibleForTesting
-@Dimension(unit = DP)
-internal const val MINIMUM_KEYBOARD_HEIGHT = 100
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/gecko/GeckoProvider.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/gecko/GeckoProvider.kt
index b0837f80cc..b25a5dbc4a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/gecko/GeckoProvider.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/gecko/GeckoProvider.kt
@@ -93,7 +93,10 @@ object GeckoProvider {
isCreditCardAutofillEnabled = { context.settings().shouldAutofillCreditCardDetails },
isAddressAutofillEnabled = { context.settings().shouldAutofillAddressDetails },
),
- GeckoLoginStorageDelegate(loginStorage),
+ GeckoLoginStorageDelegate(
+ loginStorage = loginStorage,
+ isLoginAutofillEnabled = { context.settings().shouldAutofillLogins },
+ ),
)
return geckoRuntime
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
index 75c837a62b..ac8de36e7b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
@@ -5,6 +5,7 @@
package org.mozilla.fenix.home
import android.annotation.SuppressLint
+import android.content.Intent
import android.content.res.ColorStateList
import android.content.res.Configuration
import android.graphics.drawable.ColorDrawable
@@ -13,6 +14,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.VisibleForTesting
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
@@ -80,10 +82,12 @@ import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
+import mozilla.components.support.utils.ext.isLandscape
import mozilla.components.ui.colors.PhotonColors
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.Homepage
+import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.GleanMetrics.NavigationBar
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcutCfr
import org.mozilla.fenix.HomeActivity
@@ -93,10 +97,12 @@ import org.mozilla.fenix.addons.showSnackBar
import org.mozilla.fenix.browser.BrowserAnimator
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.tabstrip.TabStrip
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.appstate.AppAction
+import org.mozilla.fenix.components.menu.MenuAccessPoint
import org.mozilla.fenix.components.toolbar.IncompleteRedesignToolbarFeature
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.components.toolbar.navbar.BottomToolbarContainerView
@@ -107,16 +113,19 @@ import org.mozilla.fenix.databinding.FragmentHomeBinding
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.containsQueryParameters
import org.mozilla.fenix.ext.hideToolbar
+import org.mozilla.fenix.ext.isTablet
import org.mozilla.fenix.ext.nav
+import org.mozilla.fenix.ext.registerForActivityResult
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.scaleToBottomOfView
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.tabClosedUndoMessage
+import org.mozilla.fenix.ext.updateNavBarForConfigurationChange
+import org.mozilla.fenix.home.bookmarks.BookmarksFeature
+import org.mozilla.fenix.home.bookmarks.controller.DefaultBookmarksController
import org.mozilla.fenix.home.pocket.DefaultPocketStoriesController
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
import org.mozilla.fenix.home.privatebrowsing.controller.DefaultPrivateBrowsingController
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmarksFeature
-import org.mozilla.fenix.home.recentbookmarks.controller.DefaultRecentBookmarksController
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabFeature
import org.mozilla.fenix.home.recentsyncedtabs.controller.DefaultRecentSyncedTabController
import org.mozilla.fenix.home.recenttabs.RecentTabsListFeature
@@ -132,6 +141,7 @@ import org.mozilla.fenix.home.toolbar.SearchSelectorBinding
import org.mozilla.fenix.home.toolbar.SearchSelectorMenuBinding
import org.mozilla.fenix.home.topsites.DefaultTopSitesView
import org.mozilla.fenix.messaging.DefaultMessageController
+import org.mozilla.fenix.messaging.FenixMessageSurfaceId
import org.mozilla.fenix.messaging.MessagingFeature
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks
@@ -233,12 +243,14 @@ class HomeFragment : Fragment() {
private val messagingFeature = ViewBoundFeatureWrapper()
private val recentTabsListFeature = ViewBoundFeatureWrapper()
private val recentSyncedTabFeature = ViewBoundFeatureWrapper()
- private val recentBookmarksFeature = ViewBoundFeatureWrapper()
+ private val bookmarksFeature = ViewBoundFeatureWrapper()
private val historyMetadataFeature = ViewBoundFeatureWrapper()
private val searchSelectorBinding = ViewBoundFeatureWrapper()
private val searchSelectorMenuBinding = ViewBoundFeatureWrapper()
private val navbarIntegration = ViewBoundFeatureWrapper()
+ private lateinit var savedLoginsLauncher: ActivityResultLauncher
+
override fun onCreate(savedInstanceState: Bundle?) {
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
val profilerStartTime = requireComponents.core.engine.profiler?.getProfilerTime()
@@ -246,6 +258,7 @@ class HomeFragment : Fragment() {
super.onCreate(savedInstanceState)
bundleArgs = args.toBundle()
+ savedLoginsLauncher = registerForActivityResult { navigateToSavedLoginsFragment() }
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
requireComponents.core.engine.profiler?.addMarker(
@@ -301,6 +314,7 @@ class HomeFragment : Fragment() {
messagingFeature.set(
feature = MessagingFeature(
appStore = requireComponents.appStore,
+ surface = FenixMessageSurfaceId.HOMESCREEN,
),
owner = viewLifecycleOwner,
view = binding.root,
@@ -347,9 +361,9 @@ class HomeFragment : Fragment() {
)
}
- if (requireContext().settings().showRecentBookmarksFeature) {
- recentBookmarksFeature.set(
- feature = RecentBookmarksFeature(
+ if (requireContext().settings().showBookmarksHomeFeature) {
+ bookmarksFeature.set(
+ feature = BookmarksFeature(
appStore = components.appStore,
bookmarksUseCase = run {
requireContext().components.useCases.bookmarksUseCases
@@ -409,7 +423,7 @@ class HomeFragment : Fragment() {
accessPoint = TabsTrayAccessPoint.HomeRecentSyncedTab,
appStore = components.appStore,
),
- recentBookmarksController = DefaultRecentBookmarksController(
+ bookmarksController = DefaultBookmarksController(
activity = activity,
navController = findNavController(),
appStore = components.appStore,
@@ -451,7 +465,11 @@ class HomeFragment : Fragment() {
searchEngine = components.core.store.state.search.selectedOrDefaultSearchEngine,
)
- if (IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled) {
+ // We don't show the navigation bar for tablets and in landscape mode.
+ val shouldAddNavigationBar = IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled &&
+ !requireContext().isLandscape() &&
+ !isTablet()
+ if (shouldAddNavigationBar) {
initializeNavBar(activity = activity)
}
@@ -478,11 +496,27 @@ class HomeFragment : Fragment() {
return binding.root
}
+ private fun reinitializeNavBar() {
+ initializeNavBar(activity = requireActivity() as HomeActivity)
+ }
+
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
homeMenuView?.dismissMenu()
+ // If the navbar feature could be visible, we should update it's state.
+ val shouldUpdateNavBarState =
+ IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled && !isTablet()
+ if (shouldUpdateNavBarState) {
+ updateNavBarForConfigurationChange(
+ parent = binding.homeLayout,
+ toolbarView = binding.toolbarLayout,
+ bottomToolbarContainerView = _bottomToolbarContainerView?.toolbarContainerView,
+ reinitializeNavBar = ::reinitializeNavBar,
+ )
+ }
+
val currentWallpaperName = requireContext().settings().currentWallpaperName
applyWallpaper(
wallpaperName = currentWallpaperName,
@@ -511,7 +545,10 @@ class HomeFragment : Fragment() {
lifecycleOwner = viewLifecycleOwner,
homeActivity = activity,
navController = findNavController(),
+ homeFragment = this,
menuButton = WeakReference(menuButton),
+ onShowPinVerification = { intent -> savedLoginsLauncher.launch(intent) },
+ onBiometricAuthenticationSuccessful = ::navigateToSavedLoginsFragment,
).also { it.build() }
_bottomToolbarContainerView = BottomToolbarContainerView(
@@ -559,7 +596,9 @@ class HomeFragment : Fragment() {
onMenuButtonClick = {
findNavController().nav(
findNavController().currentDestination?.id,
- HomeFragmentDirections.actionGlobalMenuDialogFragment(),
+ HomeFragmentDirections.actionGlobalMenuDialogFragment(
+ accesspoint = MenuAccessPoint.Home,
+ ),
)
},
)
@@ -682,7 +721,10 @@ class HomeFragment : Fragment() {
lifecycleOwner = viewLifecycleOwner,
homeActivity = activity as HomeActivity,
navController = findNavController(),
+ homeFragment = this,
menuButton = WeakReference(binding.menuButton),
+ onShowPinVerification = { intent -> savedLoginsLauncher.launch(intent) },
+ onBiometricAuthenticationSuccessful = { navigateToSavedLoginsFragment() },
).also { it.build() }
tabCounterView = TabCounterView(
@@ -693,7 +735,7 @@ class HomeFragment : Fragment() {
)
toolbarView?.build()
- if (requireContext().settings().isTabletAndTabStripEnabled) {
+ if (requireContext().isTabStripEnabled()) {
initTabStrip()
}
@@ -1224,6 +1266,18 @@ class HomeFragment : Fragment() {
}
}
+ /**
+ * Called when authentication succeeds.
+ */
+ private fun navigateToSavedLoginsFragment() {
+ val navController = findNavController()
+ if (navController.currentDestination?.id == R.id.homeFragment) {
+ Logins.openLogins.record(NoExtras())
+ val directions = HomeFragmentDirections.actionLoginsListFragment()
+ navController.navigate(directions)
+ }
+ }
+
companion object {
// Used to set homeViewModel.sessionToDelete when all tabs of a browsing mode are closed
const val ALL_NORMAL_TABS = "all_normal"
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt
index f2f7ef7522..93b9518b5a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt
@@ -49,6 +49,11 @@ class HomeMenu(
object Bookmarks : Item()
object History : Item()
object Downloads : Item()
+
+ /**
+ * The Passwords menu item
+ */
+ object Passwords : Item()
object Extensions : Item()
data class SyncAccount(val accountState: AccountState) : Item()
@@ -142,6 +147,14 @@ class HomeMenu(
onItemTapped.invoke(Item.Downloads)
}
+ val passwordsItem = BrowserMenuImageText(
+ context.getString(R.string.preferences_sync_logins_2),
+ R.drawable.mozac_ic_login_24,
+ primaryTextColor,
+ ) {
+ onItemTapped.invoke(Item.Passwords)
+ }
+
val extensionsItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_extensions),
R.drawable.ic_addons_extensions,
@@ -217,6 +230,7 @@ class HomeMenu(
bookmarksItem,
historyItem,
downloadsItem,
+ passwordsItem,
extensionsItem,
syncSignInMenuItem,
accountAuthItem,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenuView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenuView.kt
index 7a94a7837a..611946a237 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenuView.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeMenuView.kt
@@ -5,6 +5,7 @@
package org.mozilla.fenix.home
import android.content.Context
+import android.content.Intent
import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.Companion.PRIVATE
@@ -29,6 +30,7 @@ import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.settings.SupportUtils
+import org.mozilla.fenix.settings.biometric.bindBiometricsCredentialsPromptOrShowWarning
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.whatsnew.WhatsNew
@@ -43,18 +45,26 @@ import org.mozilla.fenix.GleanMetrics.HomeMenu as HomeMenuMetrics
* @param lifecycleOwner [LifecycleOwner] for the view.
* @param homeActivity [HomeActivity] used to open URLs in a new tab.
* @param navController [NavController] used for navigation.
+ * @param homeFragment [HomeFragment] used to attach the biometric prompt.
* @param menuButton The [MenuButton] that will be used to create a menu when the button is
* clicked.
* @param fxaEntrypoint The source entry point to FxA.
+ * @param onShowPinVerification Callback for registering the pin verification result.
+ * @param onBiometricAuthenticationSuccessful Callback for displaying the next screen after a
+ * successful biometric authentication.
*/
+@Suppress("LongParameterList")
class HomeMenuView(
private val view: View,
private val context: Context,
private val lifecycleOwner: LifecycleOwner,
private val homeActivity: HomeActivity,
private val navController: NavController,
+ private val homeFragment: HomeFragment,
private val menuButton: WeakReference,
private val fxaEntrypoint: FxAEntryPoint = FenixFxAEntryPoint.HomeMenu,
+ private val onShowPinVerification: (Intent) -> Unit,
+ private val onBiometricAuthenticationSuccessful: () -> Unit,
) {
/**
@@ -166,6 +176,13 @@ class HomeMenuView(
HomeFragmentDirections.actionGlobalDownloadsFragment(),
)
}
+ HomeMenu.Item.Passwords -> {
+ bindBiometricsCredentialsPromptOrShowWarning(
+ view = view,
+ onShowPinVerification = onShowPinVerification,
+ onAuthSuccess = onBiometricAuthenticationSuccessful,
+ )
+ }
HomeMenu.Item.Help -> {
HomeMenuMetrics.helpTapped.record(NoExtras())
homeActivity.openToBrowserAndLoad(
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
index 43319eb061..c8802868e8 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
@@ -19,6 +19,7 @@ import androidx.core.view.updateLayoutParams
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.support.ktx.android.content.res.resolveAttribute
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.toolbar.IncompleteRedesignToolbarFeature
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.databinding.FragmentHomeBinding
@@ -106,7 +107,7 @@ class ToolbarView(
gravity = Gravity.TOP
}
- val isTabletAndTabStripEnabled = context.settings().isTabletAndTabStripEnabled
+ val isTabletAndTabStripEnabled = context.isTabStripEnabled()
ConstraintSet().apply {
clone(binding.toolbarLayout)
clear(binding.bottomBar.id, ConstraintSet.BOTTOM)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistHandler.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistHandler.kt
index 041eb95836..80bad8fc76 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistHandler.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistHandler.kt
@@ -8,7 +8,7 @@ import android.net.Uri
import androidx.annotation.VisibleForTesting
import mozilla.components.support.ktx.kotlin.sha1
import org.mozilla.fenix.ext.containsQueryParameters
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
+import org.mozilla.fenix.home.bookmarks.Bookmark
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
import org.mozilla.fenix.home.recenttabs.RecentTab
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
@@ -37,7 +37,7 @@ class BlocklistHandler(private val settings: Settings) {
* in a scope.
*/
@JvmName("filterRecentBookmark")
- fun List.filteredByBlocklist(): List =
+ fun List.filteredByBlocklist(): List =
settings.homescreenBlocklist.let { blocklist ->
filterNot {
it.url?.let { url -> blocklistContainsUrl(blocklist, url) } ?: false
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistMiddleware.kt
index 9c8928c41d..1b65af86fa 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistMiddleware.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/blocklist/BlocklistMiddleware.kt
@@ -41,7 +41,7 @@ class BlocklistMiddleware(
when (action) {
is AppAction.Change -> {
action.copy(
- recentBookmarks = action.recentBookmarks.filteredByBlocklist(),
+ bookmarks = action.bookmarks.filteredByBlocklist(),
recentTabs = action.recentTabs.filteredByBlocklist().filterContile(),
recentHistory = action.recentHistory.filteredByBlocklist().filterContile(),
recentSyncedTabState = action.recentSyncedTabState.filteredByBlocklist().filterContile(),
@@ -52,9 +52,9 @@ class BlocklistMiddleware(
recentTabs = action.recentTabs.filteredByBlocklist().filterContile(),
)
}
- is AppAction.RecentBookmarksChange -> {
+ is AppAction.BookmarksChange -> {
action.copy(
- recentBookmarks = action.recentBookmarks.filteredByBlocklist(),
+ bookmarks = action.bookmarks.filteredByBlocklist(),
)
}
is AppAction.RecentHistoryChange -> {
@@ -73,8 +73,8 @@ class BlocklistMiddleware(
action
}
}
- is AppAction.RemoveRecentBookmark -> {
- action.recentBookmark.url?.let { url ->
+ is AppAction.RemoveBookmark -> {
+ action.bookmark.url?.let { url ->
addUrlToBlocklist(url)
state.toActionFilteringAllState(this)
} ?: action
@@ -99,7 +99,7 @@ class BlocklistMiddleware(
with(blocklistHandler) {
AppAction.Change(
recentTabs = recentTabs.filteredByBlocklist().filterContile(),
- recentBookmarks = recentBookmarks.filteredByBlocklist(),
+ bookmarks = bookmarks.filteredByBlocklist(),
recentHistory = recentHistory.filteredByBlocklist().filterContile(),
topSites = topSites,
mode = mode,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/BookmarksFeature.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/BookmarksFeature.kt
new file mode 100644
index 0000000000..79af88ea7e
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/BookmarksFeature.kt
@@ -0,0 +1,59 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks
+
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import mozilla.components.concept.storage.BookmarkNode
+import mozilla.components.support.base.feature.LifecycleAwareFeature
+import org.mozilla.fenix.components.AppStore
+import org.mozilla.fenix.components.appstate.AppAction
+import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
+import org.mozilla.fenix.home.HomeFragment
+
+/**
+ * View-bound feature that retrieves a list of [BookmarkNode]s and dispatches
+ * updates to the [AppStore].
+ *
+ * @param appStore the [AppStore] that holds the state of the [HomeFragment].
+ * @param bookmarksUseCase the [BookmarksUseCase] for retrieving the list of bookmarks from storage.
+ * @param scope the [CoroutineScope] used to fetch the bookmarks list
+ * @param ioDispatcher the [CoroutineDispatcher] for performing read/write operations.
+ */
+class BookmarksFeature(
+ private val appStore: AppStore,
+ private val bookmarksUseCase: BookmarksUseCase,
+ private val scope: CoroutineScope,
+ private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
+) : LifecycleAwareFeature {
+ private var job: Job? = null
+
+ override fun start() {
+ job = scope.launch(ioDispatcher) {
+ val bookmarks = bookmarksUseCase.retrieveRecentBookmarks()
+ appStore.dispatch(AppAction.BookmarksChange(bookmarks))
+ }
+ }
+
+ override fun stop() {
+ job?.cancel()
+ }
+}
+
+/**
+ * The simple metadata of a bookmark.
+ *
+ * @property title The title of the bookmark.
+ * @property url The url of the bookmark.
+ * @property previewImageUrl A preview image of the page (a.k.a. the hero image), if available.
+ */
+data class Bookmark(
+ val title: String? = null,
+ val url: String? = null,
+ val previewImageUrl: String? = null,
+)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/controller/BookmarksController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/controller/BookmarksController.kt
new file mode 100644
index 0000000000..6487efc1b3
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/controller/BookmarksController.kt
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks.controller
+
+import androidx.navigation.NavController
+import mozilla.appservices.places.BookmarkRoot
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.EngineSession
+import mozilla.components.concept.engine.EngineSession.LoadUrlFlags.Companion.ALLOW_JAVASCRIPT_URL
+import mozilla.components.feature.tabs.TabsUseCases
+import org.mozilla.fenix.BrowserDirection
+import org.mozilla.fenix.GleanMetrics.HomeBookmarks
+import org.mozilla.fenix.HomeActivity
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.AppStore
+import org.mozilla.fenix.components.appstate.AppAction
+import org.mozilla.fenix.home.HomeFragmentDirections
+import org.mozilla.fenix.home.bookmarks.Bookmark
+import org.mozilla.fenix.home.bookmarks.interactor.BookmarksInteractor
+
+/**
+ * An interface that handles the view manipulation of the bookmarks on the
+ * Home screen.
+ */
+interface BookmarksController {
+
+ /**
+ * @see [BookmarksInteractor.onBookmarkClicked]
+ */
+ fun handleBookmarkClicked(bookmark: Bookmark)
+
+ /**
+ * @see [BookmarksInteractor.onShowAllBookmarksClicked]
+ */
+ fun handleShowAllBookmarksClicked()
+
+ /**
+ * @see [BookmarksInteractor.onBookmarkRemoved]
+ */
+ fun handleBookmarkRemoved(bookmark: Bookmark)
+}
+
+/**
+ * The default implementation of [BookmarksController].
+ */
+class DefaultBookmarksController(
+ private val activity: HomeActivity,
+ private val navController: NavController,
+ private val appStore: AppStore,
+ private val browserStore: BrowserStore,
+ private val selectTabUseCase: TabsUseCases.SelectTabUseCase,
+) : BookmarksController {
+
+ override fun handleBookmarkClicked(bookmark: Bookmark) {
+ val existingTabForBookmark = browserStore.state.tabs.firstOrNull {
+ it.content.url == bookmark.url
+ }
+
+ if (existingTabForBookmark == null) {
+ activity.openToBrowserAndLoad(
+ searchTermOrURL = bookmark.url!!,
+ newTab = true,
+ from = BrowserDirection.FromHome,
+ flags = EngineSession.LoadUrlFlags.select(ALLOW_JAVASCRIPT_URL),
+ )
+ } else {
+ selectTabUseCase.invoke(existingTabForBookmark.id)
+ navController.navigate(R.id.browserFragment)
+ }
+
+ HomeBookmarks.bookmarkClicked.add()
+ }
+
+ override fun handleShowAllBookmarksClicked() {
+ HomeBookmarks.showAllBookmarks.add()
+ navController.navigate(
+ HomeFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id),
+ )
+ }
+
+ override fun handleBookmarkRemoved(bookmark: Bookmark) {
+ appStore.dispatch(AppAction.RemoveBookmark(bookmark))
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/interactor/BookmarksInteractor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/interactor/BookmarksInteractor.kt
new file mode 100644
index 0000000000..efe95d2979
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/interactor/BookmarksInteractor.kt
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks.interactor
+
+import org.mozilla.fenix.home.bookmarks.Bookmark
+import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
+
+/**
+ * Interface for bookmark related actions in the [SessionControlInteractor].
+ */
+interface BookmarksInteractor {
+
+ /**
+ * Opens the given bookmark in a new tab. Called when an user clicks on a bookmark on the home
+ * screen.
+ *
+ * @param bookmark The bookmark that will be opened.
+ */
+ fun onBookmarkClicked(bookmark: Bookmark)
+
+ /**
+ * Navigates to bookmark list. Called when an user clicks on the "Show all" button for
+ * bookmarks on the home screen.
+ */
+ fun onShowAllBookmarksClicked()
+
+ /**
+ * Removes a bookmark from the list on the home screen. Called when a user clicks the "Remove"
+ * button for a bookmark on the home screen.
+ *
+ * @param bookmark The bookmark that has been removed.
+ */
+ fun onBookmarkRemoved(bookmark: Bookmark)
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/Bookmarks.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/Bookmarks.kt
new file mode 100644
index 0000000000..6f70c98db8
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/Bookmarks.kt
@@ -0,0 +1,253 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks.view
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.combinedClickable
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Card
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.testTag
+import androidx.compose.ui.semantics.testTagsAsResourceId
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import mozilla.components.browser.icons.compose.Loader
+import mozilla.components.browser.icons.compose.Placeholder
+import mozilla.components.ui.colors.PhotonColors
+import org.mozilla.fenix.components.components
+import org.mozilla.fenix.compose.ContextualMenu
+import org.mozilla.fenix.compose.Favicon
+import org.mozilla.fenix.compose.Image
+import org.mozilla.fenix.compose.MenuItem
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.compose.inComposePreview
+import org.mozilla.fenix.home.bookmarks.Bookmark
+import org.mozilla.fenix.theme.FirefoxTheme
+
+private val cardShape = RoundedCornerShape(8.dp)
+
+private val imageWidth = 126.dp
+
+private val imageModifier = Modifier
+ .size(width = imageWidth, height = 82.dp)
+ .clip(cardShape)
+
+/**
+ * A list of bookmarks.
+ *
+ * @param bookmarks List of [Bookmark]s to display.
+ * @param menuItems List of [BookmarksMenuItem] shown when long clicking a [BookmarkItem]
+ * @param backgroundColor The background [Color] of each bookmark.
+ * @param onBookmarkClick Invoked when the user clicks on a bookmark.
+ */
+@OptIn(ExperimentalComposeUiApi::class)
+@Composable
+fun Bookmarks(
+ bookmarks: List,
+ menuItems: List,
+ backgroundColor: Color,
+ onBookmarkClick: (Bookmark) -> Unit = {},
+) {
+ LazyRow(
+ modifier = Modifier.semantics {
+ testTagsAsResourceId = true
+ testTag = "bookmarks"
+ },
+ contentPadding = PaddingValues(horizontal = 16.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ items(bookmarks) { bookmark ->
+ BookmarkItem(
+ bookmark = bookmark,
+ menuItems = menuItems,
+ backgroundColor = backgroundColor,
+ onBookmarkClick = onBookmarkClick,
+ )
+ }
+ }
+}
+
+/**
+ * A bookmark item.
+ *
+ * @param bookmark The [Bookmark] to display.
+ * @param menuItems The list of [BookmarksMenuItem] shown when long clicking on the bookmark item.
+ * @param backgroundColor The background [Color] of the bookmark item.
+ * @param onBookmarkClick Invoked when the user clicks on the bookmark item.
+ */
+@OptIn(
+ ExperimentalFoundationApi::class,
+ ExperimentalComposeUiApi::class,
+)
+@Composable
+private fun BookmarkItem(
+ bookmark: Bookmark,
+ menuItems: List,
+ backgroundColor: Color,
+ onBookmarkClick: (Bookmark) -> Unit = {},
+) {
+ var isMenuExpanded by remember { mutableStateOf(false) }
+
+ Card(
+ modifier = Modifier
+ .width(158.dp)
+ .combinedClickable(
+ enabled = true,
+ onClick = { onBookmarkClick(bookmark) },
+ onLongClick = { isMenuExpanded = true },
+ ),
+ shape = cardShape,
+ backgroundColor = backgroundColor,
+ elevation = 6.dp,
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp),
+ ) {
+ BookmarkImage(bookmark)
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ Text(
+ text = bookmark.title ?: bookmark.url ?: "",
+ modifier = Modifier.semantics {
+ testTagsAsResourceId = true
+ testTag = "bookmark.title"
+ },
+ color = FirefoxTheme.colors.textPrimary,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ style = FirefoxTheme.typography.caption,
+ )
+
+ ContextualMenu(
+ showMenu = isMenuExpanded,
+ onDismissRequest = { isMenuExpanded = false },
+ menuItems = menuItems.map { item -> MenuItem(item.title) { item.onClick(bookmark) } },
+ modifier = Modifier.semantics {
+ testTagsAsResourceId = true
+ testTag = "bookmark.menu"
+ },
+ )
+ }
+ }
+}
+
+@Composable
+private fun BookmarkImage(bookmark: Bookmark) {
+ when {
+ !bookmark.previewImageUrl.isNullOrEmpty() -> {
+ Image(
+ url = bookmark.previewImageUrl,
+ modifier = imageModifier,
+ targetSize = imageWidth,
+ contentScale = ContentScale.Crop,
+ fallback = {
+ if (!bookmark.url.isNullOrEmpty()) {
+ FallbackBookmarkFaviconImage(url = bookmark.url)
+ }
+ },
+ )
+ }
+ !bookmark.url.isNullOrEmpty() && !inComposePreview -> {
+ components.core.icons.Loader(bookmark.url) {
+ Placeholder {
+ PlaceholderBookmarkImage()
+ }
+
+ FallbackBookmarkFaviconImage(bookmark.url)
+ }
+ }
+ inComposePreview -> {
+ PlaceholderBookmarkImage()
+ }
+ }
+}
+
+@Composable
+private fun PlaceholderBookmarkImage() {
+ Box(
+ modifier = imageModifier.background(
+ color = when (isSystemInDarkTheme()) {
+ true -> PhotonColors.DarkGrey60
+ false -> PhotonColors.LightGrey30
+ },
+ ),
+ )
+}
+
+@Composable
+private fun FallbackBookmarkFaviconImage(
+ url: String,
+) {
+ Box(
+ modifier = imageModifier.background(
+ color = FirefoxTheme.colors.layer2,
+ ),
+ contentAlignment = Alignment.Center,
+ ) {
+ Favicon(url = url, size = 36.dp)
+ }
+}
+
+@Composable
+@LightDarkPreview
+private fun BookmarksPreview() {
+ FirefoxTheme {
+ Bookmarks(
+ bookmarks = listOf(
+ Bookmark(
+ title = "Other Bookmark Title",
+ url = "https://www.example.com",
+ previewImageUrl = null,
+ ),
+ Bookmark(
+ title = "Other Bookmark Title",
+ url = "https://www.example.com",
+ previewImageUrl = null,
+ ),
+ Bookmark(
+ title = "Other Bookmark Title",
+ url = "https://www.example.com",
+ previewImageUrl = null,
+ ),
+ Bookmark(
+ title = "Other Bookmark Title",
+ url = "https://www.example.com",
+ previewImageUrl = null,
+ ),
+ ),
+ menuItems = listOf(),
+ backgroundColor = FirefoxTheme.colors.layer2,
+ )
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksHeaderViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksHeaderViewHolder.kt
new file mode 100644
index 0000000000..354524b7cb
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksHeaderViewHolder.kt
@@ -0,0 +1,61 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks.view
+
+import android.view.View
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.LifecycleOwner
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.ComposeViewHolder
+import org.mozilla.fenix.compose.home.HomeSectionHeader
+import org.mozilla.fenix.home.bookmarks.interactor.BookmarksInteractor
+
+/**
+ * View holder for the bookmarks header and "Show all" button.
+ *
+ * @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
+ * @param viewLifecycleOwner [LifecycleOwner] life cycle owner for the view.
+ * @param interactor [BookmarksInteractor] which will have delegated to all user interactions.
+ */
+class BookmarksHeaderViewHolder(
+ composeView: ComposeView,
+ viewLifecycleOwner: LifecycleOwner,
+ private val interactor: BookmarksInteractor,
+) : ComposeViewHolder(composeView, viewLifecycleOwner) {
+
+ init {
+ val horizontalPadding =
+ composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
+ composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
+ }
+
+ @Composable
+ override fun Content() {
+ Column {
+ Spacer(modifier = Modifier.height(40.dp))
+
+ HomeSectionHeader(
+ headerText = stringResource(R.string.home_bookmarks_title),
+ description = stringResource(R.string.home_bookmarks_show_all_content_description),
+ onShowAllClick = {
+ interactor.onShowAllBookmarksClicked()
+ },
+ )
+
+ Spacer(Modifier.height(16.dp))
+ }
+ }
+
+ companion object {
+ val LAYOUT_ID = View.generateViewId()
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksMenuItem.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksMenuItem.kt
new file mode 100644
index 0000000000..b447a71166
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksMenuItem.kt
@@ -0,0 +1,18 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks.view
+
+import org.mozilla.fenix.home.bookmarks.Bookmark
+
+/**
+ * A menu item in the bookmarks dropdown menu.
+ *
+ * @property title The menu item title.
+ * @property onClick Invoked when the user clicks on the menu item.
+ */
+data class BookmarksMenuItem(
+ val title: String,
+ val onClick: (Bookmark) -> Unit,
+)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksViewHolder.kt
new file mode 100644
index 0000000000..de77577701
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/bookmarks/view/BookmarksViewHolder.kt
@@ -0,0 +1,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.bookmarks.view
+
+import android.view.View
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.res.stringResource
+import androidx.lifecycle.LifecycleOwner
+import mozilla.components.lib.state.ext.observeAsComposableState
+import mozilla.components.service.glean.private.NoExtras
+import org.mozilla.fenix.GleanMetrics.HomeBookmarks
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.components
+import org.mozilla.fenix.compose.ComposeViewHolder
+import org.mozilla.fenix.home.bookmarks.interactor.BookmarksInteractor
+import org.mozilla.fenix.wallpapers.WallpaperState
+
+/**
+ * ViewHolder for the Bookmarks section in the HomeFragment.
+ */
+class BookmarksViewHolder(
+ composeView: ComposeView,
+ viewLifecycleOwner: LifecycleOwner,
+ val interactor: BookmarksInteractor,
+) : ComposeViewHolder(composeView, viewLifecycleOwner) {
+
+ init {
+ HomeBookmarks.shown.record(NoExtras())
+ }
+
+ companion object {
+ val LAYOUT_ID = View.generateViewId()
+ }
+
+ @Composable
+ override fun Content() {
+ val bookmarks = components.appStore.observeAsComposableState { state -> state.bookmarks }
+ val wallpaperState = components.appStore
+ .observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
+
+ Bookmarks(
+ bookmarks = bookmarks.value ?: emptyList(),
+ backgroundColor = wallpaperState.wallpaperCardColor,
+ onBookmarkClick = interactor::onBookmarkClicked,
+ menuItems = listOf(
+ BookmarksMenuItem(
+ stringResource(id = R.string.home_bookmarks_menu_item_remove),
+ onClick = { bookmark -> interactor.onBookmarkRemoved(bookmark) },
+ ),
+ ),
+ )
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt
index cd70ec0612..80b783b5da 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/collections/CollectionViewHolder.kt
@@ -141,7 +141,7 @@ private fun getMenuItems(
MenuItem(
title = stringResource(R.string.collection_delete),
- color = FirefoxTheme.colors.textWarning,
+ color = FirefoxTheme.colors.textCritical,
) {
onDeleteCollectionTapped(collection)
},
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/intent/OpenRecentlyClosedIntentProcessor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/intent/OpenRecentlyClosedIntentProcessor.kt
new file mode 100644
index 0000000000..441e2af7f1
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/intent/OpenRecentlyClosedIntentProcessor.kt
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.home.intent
+
+import android.content.Intent
+import androidx.navigation.NavController
+import org.mozilla.fenix.NavGraphDirections
+import org.mozilla.fenix.ext.nav
+
+/**
+ * Opens the "recently closed tabs" fragment when the user taps on a
+ * "synced tabs closed" notification.
+ */
+class OpenRecentlyClosedIntentProcessor : HomeIntentProcessor {
+ override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
+ return if (intent.action == ACTION_OPEN_RECENTLY_CLOSED) {
+ val directions = NavGraphDirections.actionGlobalRecentlyClosed()
+ navController.nav(null, directions)
+ true
+ } else {
+ false
+ }
+ }
+
+ companion object {
+ const val ACTION_OPEN_RECENTLY_CLOSED = "org.mozilla.fenix.open_recently_closed"
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/RecentBookmarksFeature.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/RecentBookmarksFeature.kt
deleted file mode 100644
index 3e7dc9d6c5..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/RecentBookmarksFeature.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks
-
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-import mozilla.components.concept.storage.BookmarkNode
-import mozilla.components.support.base.feature.LifecycleAwareFeature
-import org.mozilla.fenix.components.AppStore
-import org.mozilla.fenix.components.appstate.AppAction
-import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
-import org.mozilla.fenix.home.HomeFragment
-
-/**
- * View-bound feature that retrieves a list of recently added [BookmarkNode]s and dispatches
- * updates to the [AppStore].
- *
- * @param appStore the [AppStore] that holds the state of the [HomeFragment].
- * @param bookmarksUseCase the [BookmarksUseCase] for retrieving the list of recently saved
- * bookmarks from storage.
- * @param scope the [CoroutineScope] used to fetch the bookmarks list
- * @param ioDispatcher the [CoroutineDispatcher] for performing read/write operations.
- */
-class RecentBookmarksFeature(
- private val appStore: AppStore,
- private val bookmarksUseCase: BookmarksUseCase,
- private val scope: CoroutineScope,
- private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
-) : LifecycleAwareFeature {
- private var job: Job? = null
-
- override fun start() {
- job = scope.launch(ioDispatcher) {
- val bookmarks = bookmarksUseCase.retrieveRecentBookmarks()
- appStore.dispatch(AppAction.RecentBookmarksChange(bookmarks))
- }
- }
-
- override fun stop() {
- job?.cancel()
- }
-}
-
-/**
- * A bookmark that was recently added.
- *
- * @property title The title of the bookmark.
- * @property url The url of the bookmark.
- * @property previewImageUrl A preview image of the page (a.k.a. the hero image), if available.
- */
-data class RecentBookmark(
- val title: String? = null,
- val url: String? = null,
- val previewImageUrl: String? = null,
-)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt
deleted file mode 100644
index a3591d9b08..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/controller/RecentBookmarksController.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks.controller
-
-import androidx.navigation.NavController
-import mozilla.appservices.places.BookmarkRoot
-import mozilla.components.browser.state.store.BrowserStore
-import mozilla.components.concept.engine.EngineSession
-import mozilla.components.concept.engine.EngineSession.LoadUrlFlags.Companion.ALLOW_JAVASCRIPT_URL
-import mozilla.components.feature.tabs.TabsUseCases
-import org.mozilla.fenix.BrowserDirection
-import org.mozilla.fenix.GleanMetrics.RecentBookmarks
-import org.mozilla.fenix.HomeActivity
-import org.mozilla.fenix.R
-import org.mozilla.fenix.components.AppStore
-import org.mozilla.fenix.components.appstate.AppAction
-import org.mozilla.fenix.home.HomeFragmentDirections
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
-import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
-
-/**
- * An interface that handles the view manipulation of the recently saved bookmarks on the
- * Home screen.
- */
-interface RecentBookmarksController {
-
- /**
- * @see [RecentBookmarksInteractor.onRecentBookmarkClicked]
- */
- fun handleBookmarkClicked(bookmark: RecentBookmark)
-
- /**
- * @see [RecentBookmarksInteractor.onShowAllBookmarksClicked]
- */
- fun handleShowAllBookmarksClicked()
-
- /**
- * @see [RecentBookmarksInteractor.onRecentBookmarkRemoved]
- */
- fun handleBookmarkRemoved(bookmark: RecentBookmark)
-}
-
-/**
- * The default implementation of [RecentBookmarksController].
- */
-class DefaultRecentBookmarksController(
- private val activity: HomeActivity,
- private val navController: NavController,
- private val appStore: AppStore,
- private val browserStore: BrowserStore,
- private val selectTabUseCase: TabsUseCases.SelectTabUseCase,
-) : RecentBookmarksController {
-
- override fun handleBookmarkClicked(bookmark: RecentBookmark) {
- val existingTabForBookmark = browserStore.state.tabs.firstOrNull {
- it.content.url == bookmark.url
- }
-
- if (existingTabForBookmark == null) {
- activity.openToBrowserAndLoad(
- searchTermOrURL = bookmark.url!!,
- newTab = true,
- from = BrowserDirection.FromHome,
- flags = EngineSession.LoadUrlFlags.select(ALLOW_JAVASCRIPT_URL),
- )
- } else {
- selectTabUseCase.invoke(existingTabForBookmark.id)
- navController.navigate(R.id.browserFragment)
- }
-
- RecentBookmarks.bookmarkClicked.add()
- }
-
- override fun handleShowAllBookmarksClicked() {
- RecentBookmarks.showAllBookmarks.add()
- navController.navigate(
- HomeFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id),
- )
- }
-
- override fun handleBookmarkRemoved(bookmark: RecentBookmark) {
- appStore.dispatch(AppAction.RemoveRecentBookmark(bookmark))
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt
deleted file mode 100644
index 810da7e14a..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/interactor/RecentBookmarksInteractor.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks.interactor
-
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
-import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
-
-/**
- * Interface for recently saved bookmark related actions in the [SessionControlInteractor].
- */
-interface RecentBookmarksInteractor {
-
- /**
- * Opens the given bookmark in a new tab. Called when an user clicks on a recently saved
- * bookmark on the home screen.
- *
- * @param bookmark The bookmark that will be opened.
- */
- fun onRecentBookmarkClicked(bookmark: RecentBookmark)
-
- /**
- * Navigates to bookmark list. Called when an user clicks on the "Show all" button for
- * recently saved bookmarks on the home screen.
- */
- fun onShowAllBookmarksClicked()
-
- /**
- * Removes a bookmark from the recent bookmark list. Called when a user clicks the "Remove"
- * button for recently saved bookmarks on the home screen.
- *
- * @param bookmark The bookmark that has been removed.
- */
- fun onRecentBookmarkRemoved(bookmark: RecentBookmark)
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt
deleted file mode 100644
index df32d3940b..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarks.kt
+++ /dev/null
@@ -1,253 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks.view
-
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.background
-import androidx.compose.foundation.combinedClickable
-import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.lazy.LazyRow
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Card
-import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.semantics.testTag
-import androidx.compose.ui.semantics.testTagsAsResourceId
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.unit.dp
-import mozilla.components.browser.icons.compose.Loader
-import mozilla.components.browser.icons.compose.Placeholder
-import mozilla.components.ui.colors.PhotonColors
-import org.mozilla.fenix.components.components
-import org.mozilla.fenix.compose.ContextualMenu
-import org.mozilla.fenix.compose.Favicon
-import org.mozilla.fenix.compose.Image
-import org.mozilla.fenix.compose.MenuItem
-import org.mozilla.fenix.compose.annotation.LightDarkPreview
-import org.mozilla.fenix.compose.inComposePreview
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
-import org.mozilla.fenix.theme.FirefoxTheme
-
-private val cardShape = RoundedCornerShape(8.dp)
-
-private val imageWidth = 126.dp
-
-private val imageModifier = Modifier
- .size(width = imageWidth, height = 82.dp)
- .clip(cardShape)
-
-/**
- * A list of recent bookmarks.
- *
- * @param bookmarks List of [RecentBookmark]s to display.
- * @param menuItems List of [RecentBookmarksMenuItem] shown when long clicking a [RecentBookmarkItem]
- * @param backgroundColor The background [Color] of each bookmark.
- * @param onRecentBookmarkClick Invoked when the user clicks on a recent bookmark.
- */
-@OptIn(ExperimentalComposeUiApi::class)
-@Composable
-fun RecentBookmarks(
- bookmarks: List,
- menuItems: List,
- backgroundColor: Color,
- onRecentBookmarkClick: (RecentBookmark) -> Unit = {},
-) {
- LazyRow(
- modifier = Modifier.semantics {
- testTagsAsResourceId = true
- testTag = "recent.bookmarks"
- },
- contentPadding = PaddingValues(horizontal = 16.dp),
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- items(bookmarks) { bookmark ->
- RecentBookmarkItem(
- bookmark = bookmark,
- menuItems = menuItems,
- backgroundColor = backgroundColor,
- onRecentBookmarkClick = onRecentBookmarkClick,
- )
- }
- }
-}
-
-/**
- * A recent bookmark item.
- *
- * @param bookmark The [RecentBookmark] to display.
- * @param menuItems The list of [RecentBookmarksMenuItem] shown when long clicking on the recent bookmark item.
- * @param backgroundColor The background [Color] of the recent bookmark item.
- * @param onRecentBookmarkClick Invoked when the user clicks on the recent bookmark item.
- */
-@OptIn(
- ExperimentalFoundationApi::class,
- ExperimentalComposeUiApi::class,
-)
-@Composable
-private fun RecentBookmarkItem(
- bookmark: RecentBookmark,
- menuItems: List,
- backgroundColor: Color,
- onRecentBookmarkClick: (RecentBookmark) -> Unit = {},
-) {
- var isMenuExpanded by remember { mutableStateOf(false) }
-
- Card(
- modifier = Modifier
- .width(158.dp)
- .combinedClickable(
- enabled = true,
- onClick = { onRecentBookmarkClick(bookmark) },
- onLongClick = { isMenuExpanded = true },
- ),
- shape = cardShape,
- backgroundColor = backgroundColor,
- elevation = 6.dp,
- ) {
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp),
- ) {
- RecentBookmarkImage(bookmark)
-
- Spacer(modifier = Modifier.height(8.dp))
-
- Text(
- text = bookmark.title ?: bookmark.url ?: "",
- modifier = Modifier.semantics {
- testTagsAsResourceId = true
- testTag = "recent.bookmark.title"
- },
- color = FirefoxTheme.colors.textPrimary,
- overflow = TextOverflow.Ellipsis,
- maxLines = 1,
- style = FirefoxTheme.typography.caption,
- )
-
- ContextualMenu(
- showMenu = isMenuExpanded,
- onDismissRequest = { isMenuExpanded = false },
- menuItems = menuItems.map { item -> MenuItem(item.title) { item.onClick(bookmark) } },
- modifier = Modifier.semantics {
- testTagsAsResourceId = true
- testTag = "recent.bookmark.menu"
- },
- )
- }
- }
-}
-
-@Composable
-private fun RecentBookmarkImage(bookmark: RecentBookmark) {
- when {
- !bookmark.previewImageUrl.isNullOrEmpty() -> {
- Image(
- url = bookmark.previewImageUrl,
- modifier = imageModifier,
- targetSize = imageWidth,
- contentScale = ContentScale.Crop,
- fallback = {
- if (!bookmark.url.isNullOrEmpty()) {
- FallbackBookmarkFaviconImage(url = bookmark.url)
- }
- },
- )
- }
- !bookmark.url.isNullOrEmpty() && !inComposePreview -> {
- components.core.icons.Loader(bookmark.url) {
- Placeholder {
- PlaceholderBookmarkImage()
- }
-
- FallbackBookmarkFaviconImage(bookmark.url)
- }
- }
- inComposePreview -> {
- PlaceholderBookmarkImage()
- }
- }
-}
-
-@Composable
-private fun PlaceholderBookmarkImage() {
- Box(
- modifier = imageModifier.background(
- color = when (isSystemInDarkTheme()) {
- true -> PhotonColors.DarkGrey60
- false -> PhotonColors.LightGrey30
- },
- ),
- )
-}
-
-@Composable
-private fun FallbackBookmarkFaviconImage(
- url: String,
-) {
- Box(
- modifier = imageModifier.background(
- color = FirefoxTheme.colors.layer2,
- ),
- contentAlignment = Alignment.Center,
- ) {
- Favicon(url = url, size = 36.dp)
- }
-}
-
-@Composable
-@LightDarkPreview
-private fun RecentBookmarksPreview() {
- FirefoxTheme {
- RecentBookmarks(
- bookmarks = listOf(
- RecentBookmark(
- title = "Other Bookmark Title",
- url = "https://www.example.com",
- previewImageUrl = null,
- ),
- RecentBookmark(
- title = "Other Bookmark Title",
- url = "https://www.example.com",
- previewImageUrl = null,
- ),
- RecentBookmark(
- title = "Other Bookmark Title",
- url = "https://www.example.com",
- previewImageUrl = null,
- ),
- RecentBookmark(
- title = "Other Bookmark Title",
- url = "https://www.example.com",
- previewImageUrl = null,
- ),
- ),
- menuItems = listOf(),
- backgroundColor = FirefoxTheme.colors.layer2,
- )
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt
deleted file mode 100644
index 210bad9623..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksHeaderViewHolder.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks.view
-
-import android.view.View
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.height
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
-import androidx.lifecycle.LifecycleOwner
-import org.mozilla.fenix.R
-import org.mozilla.fenix.compose.ComposeViewHolder
-import org.mozilla.fenix.compose.home.HomeSectionHeader
-import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
-
-/**
- * View holder for the recent bookmarks header and "Show all" button.
- *
- * @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
- * @param viewLifecycleOwner [LifecycleOwner] life cycle owner for the view.
- * @param interactor [RecentBookmarksInteractor] which will have delegated to all user interactions.
- */
-class RecentBookmarksHeaderViewHolder(
- composeView: ComposeView,
- viewLifecycleOwner: LifecycleOwner,
- private val interactor: RecentBookmarksInteractor,
-) : ComposeViewHolder(composeView, viewLifecycleOwner) {
-
- init {
- val horizontalPadding =
- composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
- composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
- }
-
- @Composable
- override fun Content() {
- Column {
- Spacer(modifier = Modifier.height(40.dp))
-
- HomeSectionHeader(
- headerText = stringResource(R.string.recently_saved_title),
- description = stringResource(R.string.recently_saved_show_all_content_description_2),
- onShowAllClick = {
- interactor.onShowAllBookmarksClicked()
- },
- )
-
- Spacer(Modifier.height(16.dp))
- }
- }
-
- companion object {
- val LAYOUT_ID = View.generateViewId()
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksMenuItem.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksMenuItem.kt
deleted file mode 100644
index 961245ce1f..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksMenuItem.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks.view
-
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
-
-/**
- * A menu item in the recent bookmarks dropdown menu.
- *
- * @property title The menu item title.
- * @property onClick Invoked when the user clicks on the menu item.
- */
-data class RecentBookmarksMenuItem(
- val title: String,
- val onClick: (RecentBookmark) -> Unit,
-)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt
deleted file mode 100644
index 13912bd041..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/recentbookmarks/view/RecentBookmarksViewHolder.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.home.recentbookmarks.view
-
-import android.view.View
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.res.stringResource
-import androidx.lifecycle.LifecycleOwner
-import mozilla.components.lib.state.ext.observeAsComposableState
-import mozilla.components.service.glean.private.NoExtras
-import org.mozilla.fenix.R
-import org.mozilla.fenix.components.components
-import org.mozilla.fenix.compose.ComposeViewHolder
-import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
-import org.mozilla.fenix.wallpapers.WallpaperState
-import org.mozilla.fenix.GleanMetrics.RecentBookmarks as RecentBookmarksMetrics
-
-class RecentBookmarksViewHolder(
- composeView: ComposeView,
- viewLifecycleOwner: LifecycleOwner,
- val interactor: RecentBookmarksInteractor,
-) : ComposeViewHolder(composeView, viewLifecycleOwner) {
-
- init {
- RecentBookmarksMetrics.shown.record(NoExtras())
- }
-
- companion object {
- val LAYOUT_ID = View.generateViewId()
- }
-
- @Composable
- override fun Content() {
- val recentBookmarks = components.appStore.observeAsComposableState { state -> state.recentBookmarks }
- val wallpaperState = components.appStore
- .observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
-
- RecentBookmarks(
- bookmarks = recentBookmarks.value ?: emptyList(),
- backgroundColor = wallpaperState.wallpaperCardColor,
- onRecentBookmarkClick = interactor::onRecentBookmarkClicked,
- menuItems = listOf(
- RecentBookmarksMenuItem(
- stringResource(id = R.string.recently_saved_menu_item_remove),
- onClick = { bookmark -> interactor.onRecentBookmarkRemoved(bookmark) },
- ),
- ),
- )
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
index ff93260109..4b5d49e697 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
@@ -18,13 +18,13 @@ import mozilla.components.service.nimbus.messaging.Message
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.home.BottomSpacerViewHolder
import org.mozilla.fenix.home.TopPlaceholderViewHolder
+import org.mozilla.fenix.home.bookmarks.view.BookmarksHeaderViewHolder
+import org.mozilla.fenix.home.bookmarks.view.BookmarksViewHolder
import org.mozilla.fenix.home.collections.CollectionViewHolder
import org.mozilla.fenix.home.collections.TabInCollectionViewHolder
import org.mozilla.fenix.home.pocket.PocketCategoriesViewHolder
import org.mozilla.fenix.home.pocket.PocketRecommendationsHeaderViewHolder
import org.mozilla.fenix.home.pocket.PocketStoriesViewHolder
-import org.mozilla.fenix.home.recentbookmarks.view.RecentBookmarksHeaderViewHolder
-import org.mozilla.fenix.home.recentbookmarks.view.RecentBookmarksViewHolder
import org.mozilla.fenix.home.recentsyncedtabs.view.RecentSyncedTabViewHolder
import org.mozilla.fenix.home.recenttabs.view.RecentTabViewHolder
import org.mozilla.fenix.home.recenttabs.view.RecentTabsHeaderViewHolder
@@ -155,8 +155,15 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
object RecentVisitsHeader : AdapterItem(RecentVisitsHeaderViewHolder.LAYOUT_ID)
object RecentVisitsItems : AdapterItem(RecentlyVisitedViewHolder.LAYOUT_ID)
- object RecentBookmarksHeader : AdapterItem(RecentBookmarksHeaderViewHolder.LAYOUT_ID)
- object RecentBookmarks : AdapterItem(RecentBookmarksViewHolder.LAYOUT_ID)
+ /**
+ * The header for the Bookmarks section.
+ */
+ object BookmarksHeader : AdapterItem(BookmarksHeaderViewHolder.LAYOUT_ID)
+
+ /**
+ * The Bookmarks section.
+ */
+ object Bookmarks : AdapterItem(BookmarksViewHolder.LAYOUT_ID)
object PocketStoriesItem : AdapterItem(PocketStoriesViewHolder.LAYOUT_ID)
object PocketCategoriesItem : AdapterItem(PocketCategoriesViewHolder.LAYOUT_ID)
@@ -230,7 +237,7 @@ class SessionControlAdapter(
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor,
)
- RecentBookmarksViewHolder.LAYOUT_ID -> return RecentBookmarksViewHolder(
+ BookmarksViewHolder.LAYOUT_ID -> return BookmarksViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor,
@@ -255,7 +262,7 @@ class SessionControlAdapter(
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor,
)
- RecentBookmarksHeaderViewHolder.LAYOUT_ID -> return RecentBookmarksHeaderViewHolder(
+ BookmarksHeaderViewHolder.LAYOUT_ID -> return BookmarksHeaderViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor,
@@ -314,8 +321,8 @@ class SessionControlAdapter(
is CustomizeHomeButtonViewHolder,
is RecentlyVisitedViewHolder,
is RecentVisitsHeaderViewHolder,
- is RecentBookmarksViewHolder,
- is RecentBookmarksHeaderViewHolder,
+ is BookmarksViewHolder,
+ is BookmarksHeaderViewHolder,
is RecentTabViewHolder,
is RecentSyncedTabViewHolder,
is RecentTabsHeaderViewHolder,
@@ -394,7 +401,7 @@ class SessionControlAdapter(
}
is TopSitesViewHolder,
is RecentlyVisitedViewHolder,
- is RecentBookmarksViewHolder,
+ is BookmarksViewHolder,
is RecentTabViewHolder,
is RecentSyncedTabViewHolder,
is PocketStoriesViewHolder,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
index 6f429e6dfb..a5412eeb9a 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
@@ -32,10 +32,10 @@ import mozilla.components.ui.widgets.withCenterAlignedButtons
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.Collections
+import org.mozilla.fenix.GleanMetrics.HomeBookmarks
import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.Pings
import org.mozilla.fenix.GleanMetrics.Pocket
-import org.mozilla.fenix.GleanMetrics.RecentBookmarks
import org.mozilla.fenix.GleanMetrics.RecentTabs
import org.mozilla.fenix.GleanMetrics.TopSites
import org.mozilla.fenix.HomeActivity
@@ -551,6 +551,6 @@ class DefaultSessionControlController(
RecentTabs.sectionVisible.set(true)
}
- RecentBookmarks.recentBookmarksCount.set(state.recentBookmarks.size.toLong())
+ HomeBookmarks.bookmarksCount.set(state.bookmarks.size.toLong())
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
index 8ef6086cfe..f5d214fd92 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
@@ -11,14 +11,14 @@ import mozilla.components.service.nimbus.messaging.Message
import mozilla.components.service.pocket.PocketStory
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.appstate.AppState
+import org.mozilla.fenix.home.bookmarks.Bookmark
+import org.mozilla.fenix.home.bookmarks.controller.BookmarksController
+import org.mozilla.fenix.home.bookmarks.interactor.BookmarksInteractor
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
import org.mozilla.fenix.home.pocket.PocketStoriesController
import org.mozilla.fenix.home.pocket.PocketStoriesInteractor
import org.mozilla.fenix.home.privatebrowsing.controller.PrivateBrowsingController
import org.mozilla.fenix.home.privatebrowsing.interactor.PrivateBrowsingInteractor
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
-import org.mozilla.fenix.home.recentbookmarks.controller.RecentBookmarksController
-import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTab
import org.mozilla.fenix.home.recentsyncedtabs.controller.RecentSyncedTabController
import org.mozilla.fenix.home.recentsyncedtabs.interactor.RecentSyncedTabInteractor
@@ -229,7 +229,7 @@ class SessionControlInteractor(
private val controller: SessionControlController,
private val recentTabController: RecentTabController,
private val recentSyncedTabController: RecentSyncedTabController,
- private val recentBookmarksController: RecentBookmarksController,
+ private val bookmarksController: BookmarksController,
private val recentVisitsController: RecentVisitsController,
private val pocketStoriesController: PocketStoriesController,
private val privateBrowsingController: PrivateBrowsingController,
@@ -242,7 +242,7 @@ class SessionControlInteractor(
MessageCardInteractor,
RecentTabInteractor,
RecentSyncedTabInteractor,
- RecentBookmarksInteractor,
+ BookmarksInteractor,
RecentVisitsInteractor,
CustomizeHomeIteractor,
PocketStoriesInteractor,
@@ -366,16 +366,16 @@ class SessionControlInteractor(
recentSyncedTabController.handleRecentSyncedTabRemoved(tab)
}
- override fun onRecentBookmarkClicked(bookmark: RecentBookmark) {
- recentBookmarksController.handleBookmarkClicked(bookmark)
+ override fun onBookmarkClicked(bookmark: Bookmark) {
+ bookmarksController.handleBookmarkClicked(bookmark)
}
override fun onShowAllBookmarksClicked() {
- recentBookmarksController.handleShowAllBookmarksClicked()
+ bookmarksController.handleShowAllBookmarksClicked()
}
- override fun onRecentBookmarkRemoved(bookmark: RecentBookmark) {
- recentBookmarksController.handleBookmarkRemoved(bookmark)
+ override fun onBookmarkRemoved(bookmark: Bookmark) {
+ bookmarksController.handleBookmarkRemoved(bookmark)
}
override fun onHistoryShowAllClicked() {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
index 3e7e9ddee7..902d7d8688 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
@@ -20,7 +20,7 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.shouldShowRecentSyncedTabs
import org.mozilla.fenix.ext.shouldShowRecentTabs
-import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
+import org.mozilla.fenix.home.bookmarks.Bookmark
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
import org.mozilla.fenix.messaging.FenixMessageSurfaceId
import org.mozilla.fenix.onboarding.HomeCFRPresenter
@@ -35,7 +35,7 @@ internal fun normalModeAdapterItems(
topSites: List,
collections: List,
expandedCollections: Set,
- recentBookmarks: List,
+ bookmarks: List,
showCollectionsPlaceholder: Boolean,
nimbusMessageCard: Message? = null,
showRecentTab: Boolean,
@@ -72,10 +72,10 @@ internal fun normalModeAdapterItems(
}
}
- if (settings.showRecentBookmarksFeature && recentBookmarks.isNotEmpty()) {
+ if (settings.showBookmarksHomeFeature && bookmarks.isNotEmpty()) {
shouldShowCustomizeHome = true
- items.add(AdapterItem.RecentBookmarksHeader)
- items.add(AdapterItem.RecentBookmarks)
+ items.add(AdapterItem.BookmarksHeader)
+ items.add(AdapterItem.Bookmarks)
}
if (settings.historyMetadataUIFeature && recentVisits.isNotEmpty()) {
@@ -137,7 +137,7 @@ private fun AppState.toAdapterList(settings: Settings): List = when
topSites,
collections,
expandedCollections,
- recentBookmarks,
+ bookmarks,
showCollectionPlaceholder,
messaging.messageToShow[FenixMessageSurfaceId.HOMESCREEN],
shouldShowRecentTabs(settings),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/PagerIndicator.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/PagerIndicator.kt
index 72f315d165..8046ed3dfd 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/PagerIndicator.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/PagerIndicator.kt
@@ -8,8 +8,8 @@ import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
+import android.view.ViewGroup.LayoutParams
import android.widget.LinearLayout
-import androidx.core.view.MarginLayoutParamsCompat
import org.mozilla.fenix.R
/**
@@ -46,7 +46,7 @@ class PagerIndicator : LinearLayout {
},
LayoutParams(dpToPx(DOT_SIZE_IN_DP), dpToPx(DOT_SIZE_IN_DP)).apply {
if (!isLast) {
- MarginLayoutParamsCompat.setMarginEnd(this, dpToPx(DOT_MARGIN))
+ this.setMarginEnd(dpToPx(DOT_MARGIN))
}
},
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt
index 4664675890..5afe189836 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt
@@ -67,9 +67,7 @@ class BookmarkFragment : LibraryPageFragment(), UserInteractionHan
private lateinit var bookmarkStore: BookmarkFragmentStore
private lateinit var bookmarkView: BookmarkView
- private var _bookmarkInteractor: BookmarkFragmentInteractor? = null
- private val bookmarkInteractor: BookmarkFragmentInteractor
- get() = _bookmarkInteractor!!
+ private lateinit var bookmarkInteractor: BookmarkFragmentInteractor
private val sharedViewModel: BookmarksSharedViewModel by activityViewModels()
private val desktopFolders by lazy { DesktopFolders(requireContext(), showMobileRoot = false) }
@@ -92,7 +90,7 @@ class BookmarkFragment : LibraryPageFragment(), UserInteractionHan
BookmarkFragmentStore(BookmarkFragmentState(null))
}
- _bookmarkInteractor = BookmarkFragmentInteractor(
+ bookmarkInteractor = BookmarkFragmentInteractor(
bookmarksController = DefaultBookmarkController(
activity = requireActivity() as HomeActivity,
navController = findNavController(),
@@ -191,7 +189,7 @@ class BookmarkFragment : LibraryPageFragment(), UserInteractionHan
menu.findItem(R.id.delete_bookmarks_multi_select).title =
SpannableString(getString(R.string.bookmark_menu_delete_button)).apply {
- setTextColor(requireContext(), R.attr.textWarning)
+ setTextColor(requireContext(), R.attr.textCritical)
}
}
}
@@ -391,7 +389,6 @@ class BookmarkFragment : LibraryPageFragment(), UserInteractionHan
override fun onDestroyView() {
super.onDestroyView()
- _bookmarkInteractor = null
_binding = null
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkItemMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkItemMenu.kt
index fe46380044..58864f750f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkItemMenu.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkItemMenu.kt
@@ -104,7 +104,7 @@ class BookmarkItemMenu(
},
TextMenuCandidate(
text = context.getString(R.string.bookmark_menu_delete_button),
- textStyle = TextStyle(color = context.getColorFromAttr(R.attr.textWarning)),
+ textStyle = TextStyle(color = context.getColorFromAttr(R.attr.textCritical)),
) {
onItemTapped.invoke(Item.Delete)
},
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt
index b80b013eba..e3e8affee8 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt
@@ -299,7 +299,7 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark), MenuProv
ColorStateList.valueOf(
ContextCompat.getColor(
requireContext(),
- R.color.fx_mobile_text_color_warning,
+ R.color.fx_mobile_text_color_critical,
),
),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt
index 2fcac34ab1..34d68916b9 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt
@@ -165,7 +165,7 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan
menu.findItem(R.id.delete_downloads_multi_select)?.title =
SpannableString(getString(R.string.download_delete_item_1)).apply {
- setTextColor(requireContext(), R.attr.textWarning)
+ setTextColor(requireContext(), R.attr.textCritical)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadItemMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadItemMenu.kt
index e1c4dc4407..a747139d97 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadItemMenu.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadItemMenu.kt
@@ -34,7 +34,7 @@ class DownloadItemMenu(
TextMenuCandidate(
text = context.getString(R.string.history_delete_item),
textStyle = TextStyle(
- color = context.getColorFromAttr(R.attr.textWarning),
+ color = context.getColorFromAttr(R.attr.textCritical),
),
) {
onItemTapped.invoke(Item.Delete)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt
index fbeda874b7..5de7644db3 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt
@@ -254,7 +254,7 @@ class HistoryFragment : LibraryPageFragment(), UserInteractionHandler,
menu.findItem(R.id.share_history_multi_select)?.isVisible = true
menu.findItem(R.id.delete_history_multi_select)?.title =
SpannableString(getString(R.string.bookmark_menu_delete_button)).apply {
- setTextColor(requireContext(), R.attr.textWarning)
+ setTextColor(requireContext(), R.attr.textCritical)
}
} else {
inflater.inflate(R.menu.history_menu, menu)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/historymetadata/HistoryMetadataGroupFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/historymetadata/HistoryMetadataGroupFragment.kt
index 7ba3a9cf13..e84fbbc440 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/historymetadata/HistoryMetadataGroupFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/historymetadata/HistoryMetadataGroupFragment.kt
@@ -157,7 +157,7 @@ class HistoryMetadataGroupFragment :
menu.findItem(R.id.delete_history_multi_select)?.let { deleteItem ->
deleteItem.title = SpannableString(deleteItem.title).apply {
- setTextColor(requireContext(), R.attr.textWarning)
+ setTextColor(requireContext(), R.attr.textCritical)
}
}
} else {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/recentlyclosed/RecentlyClosedFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/recentlyclosed/RecentlyClosedFragment.kt
index 593a9d3678..fb9aa6bfb7 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/recentlyclosed/RecentlyClosedFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/library/recentlyclosed/RecentlyClosedFragment.kt
@@ -58,7 +58,7 @@ class RecentlyClosedFragment :
inflater.inflate(R.menu.history_select_multi, menu)
menu.findItem(R.id.delete_history_multi_select)?.let { deleteItem ->
deleteItem.title = SpannableString(deleteItem.title)
- .apply { setTextColor(requireContext(), R.attr.textWarning) }
+ .apply { setTextColor(requireContext(), R.attr.textCritical) }
}
} else {
inflater.inflate(R.menu.library_menu, menu)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixMessageSurfaceId.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixMessageSurfaceId.kt
index f7092f6b01..e362b435cb 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixMessageSurfaceId.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixMessageSurfaceId.kt
@@ -22,4 +22,9 @@ object FenixMessageSurfaceId {
* A survey dialog that is intended to be disruptive.
*/
const val SURVEY = "survey"
+
+ /**
+ * A microsurvey UI for a specific feature.
+ */
+ const val MICROSURVEY = "microsurvey"
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessagingFeature.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessagingFeature.kt
index 9e9a5ef812..c8eb6508c7 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessagingFeature.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessagingFeature.kt
@@ -4,17 +4,18 @@
package org.mozilla.fenix.messaging
+import mozilla.components.service.nimbus.messaging.MessageSurfaceId
import mozilla.components.support.base.feature.LifecycleAwareFeature
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction
/**
- * A message observer that updates the provided.
+ * A [LifecycleAwareFeature] which tries to evaluate if message is available for the provided [surface].
*/
-class MessagingFeature(val appStore: AppStore) : LifecycleAwareFeature {
+class MessagingFeature(val appStore: AppStore, val surface: MessageSurfaceId) : LifecycleAwareFeature {
override fun start() {
- appStore.dispatch(MessagingAction.Evaluate(FenixMessageSurfaceId.HOMESCREEN))
+ appStore.dispatch(MessagingAction.Evaluate(surface))
}
override fun stop() = Unit
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyContent.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyContent.kt
new file mode 100644
index 0000000000..e89c5b64ed
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyContent.kt
@@ -0,0 +1,123 @@
+/* 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.microsurvey.ui
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Card
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.PreviewScreenSizes
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.compose.list.RadioButtonListItem
+import org.mozilla.fenix.theme.FirefoxTheme
+
+private val shape = RoundedCornerShape(16.dp)
+private val elevation: Dp = 5.dp
+
+/**
+ * The micro survey content UI to hold question and answer data.
+ *
+ * @param question The survey question text.
+ * @param answers The survey answer text options available for the question.
+ * @param icon The survey icon, this will represent the feature the survey is for.
+ * @param backgroundColor The view background color.
+ * @param selectedAnswer The current selected answer. Will be null until user selects an option.
+ * @param onSelectionChange An event that updates the [selectedAnswer].
+ */
+@Composable
+fun MicroSurveyContent(
+ question: String,
+ answers: List,
+ @DrawableRes icon: Int = R.drawable.ic_print, // todo currently unknown what the default will be if any.
+ backgroundColor: Color = FirefoxTheme.colors.layer2,
+ selectedAnswer: String? = null,
+ onSelectionChange: (String) -> Unit,
+) {
+ Card(
+ shape = shape,
+ backgroundColor = backgroundColor,
+ elevation = elevation,
+ modifier = Modifier
+ .wrapContentHeight()
+ .fillMaxWidth(),
+ ) {
+ Column(modifier = Modifier.wrapContentHeight()) {
+ Header(icon, question)
+
+ answers.forEach {
+ RadioButtonListItem(
+ label = it,
+ selected = selectedAnswer == it,
+ onClick = {
+ onSelectionChange.invoke(it)
+ },
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun Header(icon: Int, question: String) {
+ Row(
+ modifier = Modifier.padding(16.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Image(
+ painter = painterResource(icon),
+ contentDescription = "Survey icon", // todo update to string res once a11y strings are available.
+ modifier = Modifier.size(24.dp),
+ )
+
+ Spacer(modifier = Modifier.width(16.dp))
+
+ Text(
+ text = question,
+ color = FirefoxTheme.colors.textPrimary,
+ style = FirefoxTheme.typography.headline7,
+ )
+ }
+}
+
+/**
+ * Preview for [MicroSurveyContent].
+ */
+@PreviewScreenSizes
+@LightDarkPreview
+@Composable
+fun MicroSurveyContentPreview() {
+ FirefoxTheme {
+ MicroSurveyContent(
+ question = "How satisfied are you with printing in Firefox?",
+ icon = R.drawable.ic_print,
+ answers = listOf(
+ stringResource(id = R.string.likert_scale_option_1),
+ stringResource(id = R.string.likert_scale_option_2),
+ stringResource(id = R.string.likert_scale_option_3),
+ stringResource(id = R.string.likert_scale_option_4),
+ stringResource(id = R.string.likert_scale_option_5),
+ ),
+ onSelectionChange = {},
+ )
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyFooter.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyFooter.kt
new file mode 100644
index 0000000000..e9dd23c97f
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyFooter.kt
@@ -0,0 +1,105 @@
+/* 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.microsurvey.ui
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextDecoration
+import androidx.compose.ui.tooling.preview.PreviewScreenSizes
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.LinkText
+import org.mozilla.fenix.compose.LinkTextState
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * The footer UI used for micro-survey.
+ *
+ * @param isSubmitted Whether the user has "Submitted" the survey or not.
+ * @param isContentAnswerSelected Whether the user clicked on one of the answers or not.
+ * @param onLinkClick Invoked when the link is clicked.
+ * @param onButtonClick Invoked when the "Submit"/"Close" button is clicked.
+ */
+@Composable
+fun MicroSurveyFooter(
+ isSubmitted: Boolean,
+ isContentAnswerSelected: Boolean,
+ onLinkClick: () -> Unit,
+ onButtonClick: () -> Unit,
+) {
+ val buttonText = if (isSubmitted) {
+ stringResource(id = R.string.micro_survey_close_button_label)
+ } else {
+ stringResource(id = R.string.micro_survey_submit_button_label)
+ }
+ val buttonColor = if (isContentAnswerSelected) {
+ FirefoxTheme.colors.actionPrimary
+ } else {
+ FirefoxTheme.colors.actionPrimaryDisabled
+ }
+
+ Row(
+ verticalAlignment = Alignment.Bottom,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ LinkText(
+ text = stringResource(id = R.string.about_privacy_notice),
+ linkTextStates = listOf(
+ LinkTextState(
+ text = stringResource(id = R.string.micro_survey_privacy_notice),
+ url = "",
+ onClick = {
+ onLinkClick()
+ },
+ ),
+ ),
+ style = FirefoxTheme.typography.caption,
+ linkTextDecoration = TextDecoration.Underline,
+ )
+
+ Spacer(modifier = Modifier.weight(1f))
+
+ Button(
+ onClick = { onButtonClick() },
+ enabled = isContentAnswerSelected,
+ shape = RoundedCornerShape(size = 4.dp),
+ colors = ButtonDefaults.buttonColors(
+ backgroundColor = buttonColor,
+ ),
+ contentPadding = PaddingValues(16.dp, 12.dp),
+ ) {
+ Text(
+ text = buttonText,
+ color = FirefoxTheme.colors.textActionPrimary,
+ style = FirefoxTheme.typography.button,
+ )
+ }
+ }
+}
+
+@PreviewScreenSizes
+@LightDarkPreview
+@Composable
+private fun ReviewQualityCheckFooterPreview() {
+ FirefoxTheme {
+ MicroSurveyFooter(
+ isSubmitted = false,
+ isContentAnswerSelected = false,
+ onLinkClick = {},
+ onButtonClick = {},
+ )
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyHeader.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyHeader.kt
new file mode 100644
index 0000000000..77fda94dc2
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyHeader.kt
@@ -0,0 +1,86 @@
+/* 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.microsurvey.ui
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.PreviewScreenSizes
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * The header UI used for micro-survey.
+ *
+ * @param title The text that will be visible on the header.
+ * @param onCloseButtonClick Invoked when the close button is clicked.
+ */
+@Composable
+fun MicroSurveyHeader(
+ title: String,
+ onCloseButtonClick: () -> Unit,
+) {
+ Row(
+ horizontalArrangement = Arrangement.Center,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ Image(
+ painter = painterResource(R.drawable.ic_firefox),
+ contentDescription = null, // todo update to string res once a11y strings are available.
+ modifier = Modifier.size(24.dp),
+ )
+
+ Spacer(modifier = Modifier.width(8.dp))
+
+ Text(
+ text = title,
+ style = FirefoxTheme.typography.headline7,
+ color = FirefoxTheme.colors.textPrimary,
+ modifier = Modifier.weight(1f),
+ )
+
+ IconButton(onClick = onCloseButtonClick) {
+ Icon(
+ painter = painterResource(id = R.drawable.ic_close),
+ contentDescription = null, // todo update to string res once a11y strings are available.
+ tint = FirefoxTheme.colors.iconPrimary,
+ modifier = Modifier.size(20.dp),
+ )
+ }
+ }
+}
+
+@PreviewScreenSizes
+@LightDarkPreview
+@Composable
+private fun MicroSurveyHeaderPreview() {
+ FirefoxTheme {
+ Box(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer1)
+ .padding(16.dp),
+ ) {
+ MicroSurveyHeader(stringResource(R.string.micro_survey_survey_header)) {}
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyScaffold.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyScaffold.kt
new file mode 100644
index 0000000000..20294a0158
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicroSurveyScaffold.kt
@@ -0,0 +1,67 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.microsurvey.ui
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Card
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * A scaffold for micro-survey UI that implements the basic layout structure with
+ * [content].
+ *
+ * @param content The content of micro-survey.
+ */
+@Composable
+fun MicroSurveyScaffold(
+ content: @Composable () -> Unit,
+) {
+ var isOpen by remember { mutableStateOf(false) }
+ val cardShape = if (isOpen) {
+ RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp)
+ } else {
+ RectangleShape
+ }
+ val height = if (isOpen) {
+ 600.dp
+ } else {
+ 200.dp
+ }
+
+ Card(
+ shape = cardShape,
+ backgroundColor = FirefoxTheme.colors.actionQuarternary,
+ modifier = Modifier
+ .fillMaxWidth()
+ .clickable(
+ onClick = { isOpen = !isOpen },
+ ),
+ ) {
+ Column(modifier = Modifier.height(height)) {
+ content()
+ }
+ }
+}
+
+@LightDarkPreview
+@Composable
+private fun MicroSurveyScaffoldPreview() {
+ FirefoxTheme {
+ MicroSurveyScaffold {}
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyBottomSheet.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyBottomSheet.kt
new file mode 100644
index 0000000000..eaf2f63081
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyBottomSheet.kt
@@ -0,0 +1,117 @@
+/* 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.microsurvey.ui
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Surface
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.traversalIndex
+import androidx.compose.ui.tooling.preview.PreviewScreenSizes
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.BottomSheetHandle
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+
+private const val BOTTOM_SHEET_HANDLE_WIDTH_PERCENT = 0.1f
+private val bottomSheetShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp)
+
+/**
+ * The microsurvey bottom sheet.
+ *
+ * @param question The question text.
+ * @param answers The answer text options available for the given [question].
+ * @param icon The icon that represents the feature for the given [question].
+ */
+@Composable
+fun MicrosurveyBottomSheet(
+ question: String,
+ answers: List,
+ @DrawableRes icon: Int = R.drawable.ic_print, // todo currently unknown if default is used FXDROID-1921.
+) {
+ var selectedAnswer by remember { mutableStateOf(null) }
+ var isSubmitted by remember { mutableStateOf(false) }
+
+ Surface(
+ color = FirefoxTheme.colors.layer1,
+ shape = bottomSheetShape,
+ ) {
+ Column(
+ modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .padding(
+ vertical = 8.dp,
+ horizontal = 16.dp,
+ ),
+ ) {
+ BottomSheetHandle(
+ onRequestDismiss = {},
+ contentDescription = stringResource(R.string.review_quality_check_close_handle_content_description),
+ modifier = Modifier
+ .fillMaxWidth(BOTTOM_SHEET_HANDLE_WIDTH_PERCENT)
+ .align(Alignment.CenterHorizontally)
+ .semantics { traversalIndex = -1f },
+ )
+
+ Spacer(modifier = Modifier.height(4.dp))
+
+ MicroSurveyHeader(title = stringResource(id = R.string.micro_survey_survey_header)) {}
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ MicroSurveyContent(
+ question = question,
+ icon = icon,
+ answers = answers,
+ selectedAnswer = selectedAnswer,
+ onSelectionChange = { selectedAnswer = it },
+ )
+
+ Spacer(modifier = Modifier.height(24.dp))
+
+ MicroSurveyFooter(
+ isSubmitted = isSubmitted,
+ isContentAnswerSelected = selectedAnswer != null,
+ onLinkClick = {}, // todo add privacy policy link and open new tab FXDROID-1876.
+ onButtonClick = { isSubmitted = true },
+ )
+ }
+ }
+}
+
+@PreviewScreenSizes
+@LightDarkPreview
+@Composable
+private fun MicroSurveyBottomSheetPreview() {
+ FirefoxTheme {
+ MicrosurveyBottomSheet(
+ question = "How satisfied are you with printing in Firefox?",
+ icon = R.drawable.ic_print,
+ answers = listOf(
+ stringResource(id = R.string.likert_scale_option_1),
+ stringResource(id = R.string.likert_scale_option_2),
+ stringResource(id = R.string.likert_scale_option_3),
+ stringResource(id = R.string.likert_scale_option_4),
+ stringResource(id = R.string.likert_scale_option_5),
+ ),
+ )
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyBottomSheetFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyBottomSheetFragment.kt
new file mode 100644
index 0000000000..338b1f3779
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyBottomSheetFragment.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.microsurvey.ui
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.ViewCompositionStrategy
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import org.mozilla.fenix.R
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * todo update behaviour FXDROID-1944.
+ * todo pass question and icon values from messaging FXDROID-1945.
+ * todo add dismiss request FXDROID-1946.
+ */
+
+/**
+ * A bottom sheet fragment for displaying a microsurvey.
+ */
+class MicrosurveyBottomSheetFragment : BottomSheetDialogFragment() {
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
+ super.onCreateDialog(savedInstanceState).apply {
+ setOnShowListener {
+ val bottomSheet = findViewById(R.id.design_bottom_sheet)
+ bottomSheet?.setBackgroundResource(android.R.color.transparent)
+ val behavior = BottomSheetBehavior.from(bottomSheet)
+ behavior.peekHeight = resources.displayMetrics.heightPixels
+ behavior.state = BottomSheetBehavior.STATE_EXPANDED
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View = ComposeView(requireContext()).apply {
+ val answers = listOf(
+ getString(R.string.likert_scale_option_1),
+ getString(R.string.likert_scale_option_2),
+ getString(R.string.likert_scale_option_3),
+ getString(R.string.likert_scale_option_4),
+ getString(R.string.likert_scale_option_5),
+ )
+
+ setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
+
+ setContent {
+ FirefoxTheme {
+ MicrosurveyBottomSheet(
+ question = "How satisfied are you with printing in Firefox?", // todo get value from messaging
+ icon = R.drawable.ic_print, // todo get value from messaging
+ answers = answers, // todo get value from messaging
+ )
+ }
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyRequestPrompt.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyRequestPrompt.kt
new file mode 100644
index 0000000000..44d3ce71b2
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/microsurvey/ui/MicrosurveyRequestPrompt.kt
@@ -0,0 +1,96 @@
+/* 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.microsurvey.ui
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.PreviewScreenSizes
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.compose.button.PrimaryButton
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * Initial microsurvey prompt displayed to the user to request completion of feedback.
+ *
+ * @param title The prompt header title.
+ */
+@Composable
+fun MicrosurveyRequestPrompt(
+ // todo this is the message title FXDROID-1966).
+ title: String = "Help make printing in Firefox better. It only takes a sec.",
+) {
+ Column(
+ modifier = Modifier
+ .background(color = FirefoxTheme.colors.layer1)
+ .padding(all = 16.dp),
+ ) {
+ Header(title)
+
+ Spacer(modifier = Modifier.height(8.dp))
+
+ PrimaryButton(text = stringResource(id = R.string.micro_survey_continue_button_label)) {}
+ }
+}
+
+@Composable
+private fun Header(
+ title: String,
+) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ Image(
+ painter = painterResource(R.drawable.ic_firefox),
+ contentDescription = null, // todo update to string res once a11y strings are available FXDROID-1919.
+ modifier = Modifier.size(24.dp),
+ )
+
+ Spacer(modifier = Modifier.width(8.dp))
+
+ Text(
+ text = title,
+ style = FirefoxTheme.typography.headline7,
+ color = FirefoxTheme.colors.textPrimary,
+ modifier = Modifier.weight(1f),
+ )
+
+ IconButton(
+ onClick = {}, // todo FXDROID-1947.
+ modifier = Modifier.size(20.dp),
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.ic_close),
+ contentDescription = null, // todo update to string res once a11y strings are available FXDROID-1919.
+ tint = FirefoxTheme.colors.iconPrimary,
+ )
+ }
+ }
+}
+
+@PreviewScreenSizes
+@LightDarkPreview
+@Composable
+private fun MicrosurveyRequestPromptPreview() {
+ FirefoxTheme {
+ MicrosurveyRequestPrompt()
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
index 487e46b7d6..7bf2e6a547 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
@@ -10,6 +10,7 @@ import android.content.IntentFilter
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
+import android.os.StrictMode
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -29,6 +30,7 @@ import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
import org.mozilla.fenix.compose.LinkTextState
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.hideToolbar
+import org.mozilla.fenix.ext.isDefaultBrowserPromptSupported
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.openSetDefaultBrowserOption
import org.mozilla.fenix.ext.requireComponents
@@ -51,7 +53,8 @@ class OnboardingFragment : Fragment() {
private val pagesToDisplay by lazy {
pagesToDisplay(
- isNotDefaultBrowser(requireContext()),
+ isNotDefaultBrowser(requireContext()) &&
+ activity?.isDefaultBrowserPromptSupported() == false,
canShowNotificationPage(requireContext()),
canShowAddSearchWidgetPrompt(),
)
@@ -76,9 +79,11 @@ class OnboardingFragment : Fragment() {
.registerReceiver(pinAppWidgetReceiver, filter)
if (isNotDefaultBrowser(context) &&
- pagesToDisplay.none { it.type == OnboardingPageUiData.Type.DEFAULT_BROWSER }
+ activity?.isDefaultBrowserPromptSupported() == true
) {
- promptToSetAsDefaultBrowser()
+ requireComponents.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
+ promptToSetAsDefaultBrowser()
+ }
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt
index f08b1a6552..351860f442 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerStopDialogFragment.kt
@@ -56,9 +56,8 @@ class ProfilerStopDialogFragment : DialogFragment() {
}
}
- override fun dismiss() {
+ private fun setProfilerState() {
profilerViewModel.setProfilerState(requireContext().components.core.engine.profiler!!.isProfilerActive())
- super.dismiss()
}
@Composable
@@ -111,7 +110,14 @@ class ProfilerStopDialogFragment : DialogFragment() {
) {
TextButton(
onClick = {
- requireContext().components.core.engine.profiler?.stopProfiler({}, {})
+ requireContext().components.core.engine.profiler?.stopProfiler(
+ onSuccess = {
+ setProfilerState()
+ },
+ onError = {
+ setProfilerState()
+ },
+ )
dismiss()
},
) {
@@ -162,6 +168,7 @@ class ProfilerStopDialogFragment : DialogFragment() {
resources.getString(message) + extra,
Toast.LENGTH_LONG,
).show()
+ setProfilerState()
dismiss()
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt
index 28a8211e59..5fddb6500e 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/ProfilerUtils.kt
@@ -34,6 +34,7 @@ private val firefox_features = arrayOf(
"java",
"processcpu",
"ipcmessages",
+ "memory",
)
private val firefox_threads = arrayOf(
"GeckoMain",
@@ -43,7 +44,8 @@ private val firefox_threads = arrayOf(
"DOM Worker",
)
-private val graphics_features = arrayOf("stackwalk", "js", "cpu", "java", "processcpu", "ipcmessages")
+private val graphics_features =
+ arrayOf("stackwalk", "js", "cpu", "java", "processcpu", "ipcmessages", "memory")
private val graphics_threads = arrayOf(
"GeckoMain",
"Compositor",
@@ -64,6 +66,7 @@ private val media_features = arrayOf(
"ipcmessages",
"processcpu",
"java",
+ "memory",
)
private val media_threads = arrayOf(
"cubeb", "audio", "BackgroundThreadPool", "camera", "capture", "Compositor", "decoder", "GeckoMain", "gmp",
@@ -81,6 +84,7 @@ private val networking_features = arrayOf(
"processcpu",
"bandwidth",
"ipcmessages",
+ "memory",
)
private val networking_threads = arrayOf(
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt
index cd0bc2f758..def5cd4999 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt
@@ -17,6 +17,7 @@ import mozilla.components.support.ktx.android.content.res.resolveAttribute
import mozilla.components.support.ktx.android.view.hideKeyboard
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.components.toolbar.IncompleteRedesignToolbarFeature
import org.mozilla.fenix.ext.settings
@@ -139,7 +140,7 @@ class ToolbarView(
},
)
- if (settings.isTabletAndTabStripEnabled) {
+ if (context.isTabStripEnabled()) {
(layoutParams as ViewGroup.MarginLayoutParams).updateMargins(
top = context.resources.getDimensionPixelSize(R.dimen.tab_strip_height),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt
index 9f5d6b6d05..642e4d4160 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt
@@ -19,6 +19,7 @@ import org.mozilla.fenix.GleanMetrics.AppTheme
import org.mozilla.fenix.GleanMetrics.PullToRefreshInBrowser
import org.mozilla.fenix.GleanMetrics.ToolbarSettings
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
@@ -53,7 +54,7 @@ class CustomizationFragment : PreferenceFragmentCompat() {
bindLightTheme()
bindAutoBatteryTheme()
setupRadioGroups()
- val tabletAndTabStripEnabled = requireContext().settings().isTabletAndTabStripEnabled
+ val tabletAndTabStripEnabled = requireContext().isTabStripEnabled()
if (tabletAndTabStripEnabled) {
val preferenceScreen: PreferenceScreen =
requirePreference(R.string.pref_key_customization_preference_screen)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt
index 9bba8fca3d..17427cda52 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HomeSettingsFragment.kt
@@ -84,14 +84,14 @@ class HomeSettingsFragment : PreferenceFragmentCompat() {
}
}
- requirePreference(R.string.pref_key_recent_bookmarks).apply {
- isChecked = context.settings().showRecentBookmarksFeature
+ requirePreference(R.string.pref_key_customization_bookmarks).apply {
+ isChecked = context.settings().showBookmarksHomeFeature
onPreferenceChangeListener = object : SharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
CustomizeHome.preferenceToggled.record(
CustomizeHome.PreferenceToggledExtra(
newValue as Boolean,
- "recently_saved",
+ "bookmarks",
),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/PairFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/PairFragment.kt
index 5a1f3c3a10..ea82f9f13b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/PairFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/PairFragment.kt
@@ -16,6 +16,9 @@ import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import mozilla.components.feature.qr.QrFeature
+import mozilla.components.service.fxa.manager.SCOPE_PROFILE
+import mozilla.components.service.fxa.manager.SCOPE_SESSION
+import mozilla.components.service.fxa.manager.SCOPE_SYNC
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.R
@@ -54,6 +57,7 @@ class PairFragment : Fragment(R.layout.fragment_pair), UserInteractionHandler {
requireContext(),
pairingUrl,
args.entrypoint,
+ setOf(SCOPE_SYNC, SCOPE_PROFILE, SCOPE_SESSION),
)
val vibrator = requireContext().getSystemService()!!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt
index 5101f10f28..c50cbe6a1c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt
@@ -18,6 +18,7 @@ import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.isTabStripEligible
import org.mozilla.fenix.debugsettings.data.DefaultDebugSettingsRepository
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
@@ -142,7 +143,7 @@ class SecretSettingsFragment : PreferenceFragmentCompat() {
private fun setupTabStripPreference() {
requirePreference(R.string.pref_key_enable_tab_strip).apply {
- isVisible = Config.channel.isNightlyOrDebug && context.resources.getBoolean(R.bool.tablet)
+ isVisible = context.isTabStripEligible()
isChecked = context.settings().isTabStripEnabled
onPreferenceChangeListener = SharedPreferenceUpdater()
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
index d392ba8697..b6d9e1ea78 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
@@ -47,6 +47,7 @@ import org.mozilla.fenix.GleanMetrics.Addons
import org.mozilla.fenix.GleanMetrics.CookieBanners
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.TrackingProtection
+import org.mozilla.fenix.GleanMetrics.Translations
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
@@ -158,6 +159,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
updateProfilerUI(it)
},
)
+
+ findPreference(
+ getPreferenceKey(R.string.pref_key_translation),
+ )?.isVisible = FxNimbus.features.translations.value().globalSettingsEnabled
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@@ -315,6 +320,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
SettingsFragmentDirections.actionSettingsFragmentToLocaleSettingsFragment()
}
+ resources.getString(R.string.pref_key_translation) -> {
+ Translations.action.record(Translations.ActionExtra("global_settings_from_preferences"))
+ SettingsFragmentDirections.actionSettingsFragmentToTranslationsSettingsFragment()
+ }
+
/* Privacy and security preferences */
resources.getString(R.string.pref_key_private_browsing) -> {
SettingsFragmentDirections.actionSettingsFragmentToPrivateBrowsingFragment()
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
index da73fcc10e..9b0c7649ce 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
@@ -39,6 +39,11 @@ object SupportUtils {
const val GOOGLE_XX_URL = "https://www.google.com/webhp?client=firefox-b-m&channel=ts"
const val WHATS_NEW_URL = "https://www.mozilla.org/firefox/android/notes"
+ // This is locale-less on purpose so that the content negotiation happens on the AMO side because the current
+ // user language might not be supported by AMO and/or the language might not be exactly what AMO is expecting
+ // (e.g. `en` instead of `en-US`).
+ const val AMO_HOMEPAGE_FOR_ANDROID = "${BuildConfig.AMO_BASE_URL}/android/"
+
enum class SumoTopic(internal val topicStr: String) {
HELP("faq-android"),
PRIVATE_BROWSING_MYTHS("common-myths-about-private-browsing"),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SyncDebugFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SyncDebugFragment.kt
index b5a0886498..62f33c6ce3 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SyncDebugFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SyncDebugFragment.kt
@@ -11,6 +11,7 @@ import androidx.preference.Preference
import androidx.preference.Preference.OnPreferenceClickListener
import androidx.preference.PreferenceFragmentCompat
import org.mozilla.fenix.R
+import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
import kotlin.system.exitProcess
@@ -59,6 +60,24 @@ class SyncDebugFragment : PreferenceFragmentCompat() {
requirePreference(R.string.pref_key_use_react_fxa).apply {
onPreferenceChangeListener = SharedPreferenceUpdater()
}
+ requirePreference(R.string.pref_key_sync_debug_network_error).let { pref ->
+ pref.onPreferenceClickListener = OnPreferenceClickListener {
+ requireComponents.backgroundServices.accountManager.simulateNetworkError()
+ true
+ }
+ }
+ requirePreference(R.string.pref_key_sync_debug_temporary_auth_error).let { pref ->
+ pref.onPreferenceClickListener = OnPreferenceClickListener {
+ requireComponents.backgroundServices.accountManager.simulateTemporaryAuthTokenIssue()
+ true
+ }
+ }
+ requirePreference(R.string.pref_key_sync_debug_permanent_auth_error).let { pref ->
+ pref.onPreferenceClickListener = OnPreferenceClickListener {
+ requireComponents.backgroundServices.accountManager.simulatePermanentAuthTokenIssue()
+ true
+ }
+ }
updateMenu()
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/AccountProblemFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/AccountProblemFragment.kt
index 9b82a91a88..6e39f105d4 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/AccountProblemFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/AccountProblemFragment.kt
@@ -15,6 +15,8 @@ import kotlinx.coroutines.launch
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount
+import mozilla.components.service.fxa.manager.SCOPE_PROFILE
+import mozilla.components.service.fxa.manager.SCOPE_SYNC
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.SyncAuth
import org.mozilla.fenix.R
@@ -27,7 +29,11 @@ class AccountProblemFragment : PreferenceFragmentCompat(), AccountObserver {
private val args by navArgs()
private val signInClickListener = Preference.OnPreferenceClickListener {
- requireComponents.services.accountsAuthFeature.beginAuthentication(requireContext(), args.entrypoint)
+ requireComponents.services.accountsAuthFeature.beginAuthentication(
+ requireContext(),
+ args.entrypoint,
+ setOf(SCOPE_PROFILE, SCOPE_SYNC),
+ )
SyncAuth.useEmailProblem.record(NoExtras())
// TODO The sign-in web content populates session history,
// so pressing "back" after signing in won't take us back into the settings screen, but rather up the
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt
index ab03b079b7..a2e5f5b8e5 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt
@@ -17,6 +17,8 @@ import androidx.navigation.fragment.navArgs
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount
+import mozilla.components.service.fxa.manager.SCOPE_PROFILE
+import mozilla.components.service.fxa.manager.SCOPE_SYNC
import mozilla.components.support.ktx.android.content.hasCamera
import mozilla.components.support.ktx.android.content.isPermissionGranted
import mozilla.components.support.ktx.android.view.hideKeyboard
@@ -184,6 +186,7 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
requireComponents.services.accountsAuthFeature.beginAuthentication(
requireContext(),
entrypoint = args.entrypoint,
+ setOf(SCOPE_PROFILE, SCOPE_SYNC),
)
SyncAuth.useEmail.record(NoExtras())
// TODO The sign-in web content populates session history,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/biometric/BiometricUtils.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/biometric/BiometricUtils.kt
new file mode 100644
index 0000000000..db83dee4a1
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/biometric/BiometricUtils.kt
@@ -0,0 +1,110 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.settings.biometric
+
+import android.app.KeyguardManager
+import android.content.DialogInterface
+import android.content.Intent
+import android.provider.Settings
+import android.view.View
+import androidx.appcompat.app.AlertDialog
+import androidx.core.content.getSystemService
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.findFragment
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
+import mozilla.components.ui.widgets.withCenterAlignedButtons
+import org.mozilla.fenix.R
+import org.mozilla.fenix.ext.runIfFragmentIsAttached
+import org.mozilla.fenix.ext.secure
+import org.mozilla.fenix.ext.settings
+
+/**
+ * Prompts the biometric authentication before navigating to new fragment
+ * or displays warning dialog in case the feature is not available
+ */
+@Suppress("Deprecation")
+fun bindBiometricsCredentialsPromptOrShowWarning(
+ view: View,
+ onShowPinVerification: (Intent) -> Unit,
+ onAuthSuccess: () -> Unit,
+ onAuthFailure: () -> Unit = {},
+ doWhileAuthenticating: () -> Unit = {},
+) {
+ val (fragment, context) = Result.runCatching {
+ view.findFragment() as Fragment to view.context
+ }.getOrElse { return }
+
+ val biometricPromptFeature = ViewBoundFeatureWrapper(
+ owner = fragment.viewLifecycleOwner,
+ view = view,
+ feature = BiometricPromptFeature(
+ context = context,
+ fragment = fragment,
+ onAuthSuccess = {
+ fragment.runIfFragmentIsAttached {
+ fragment.lifecycleScope.launch(Dispatchers.Main) {
+ onAuthSuccess()
+ }
+ }
+ },
+ onAuthFailure = onAuthFailure,
+ ),
+ )
+ // Use the BiometricPrompt first
+ if (BiometricPromptFeature.canUseFeature(context)) {
+ doWhileAuthenticating()
+ biometricPromptFeature.get()
+ ?.requestAuthentication(context.resources.getString(R.string.logins_biometric_prompt_message_2))
+ return
+ }
+
+ // Fallback to prompting for password with the KeyguardManager
+ val manager = context.getSystemService()
+ if (manager?.isKeyguardSecure == true) {
+ val confirmDeviceCredentialIntent = manager.createConfirmDeviceCredentialIntent(
+ context.resources.getString(R.string.logins_biometric_prompt_message_pin),
+ context.resources.getString(R.string.logins_biometric_prompt_message),
+ )
+ onShowPinVerification(confirmDeviceCredentialIntent)
+ } else {
+ // Warn that the device has not been secured
+ if (context.settings().shouldShowSecurityPinWarning) {
+ fragment.activity?.let {
+ showPinDialogWarning(it, onAuthSuccess)
+ } ?: return
+ } else {
+ onAuthSuccess()
+ }
+ }
+}
+
+@Suppress("MaxLineLength")
+private fun showPinDialogWarning(
+ activity: FragmentActivity,
+ onIgnorePinWarning: () -> Unit,
+) {
+ AlertDialog.Builder(activity).apply {
+ setTitle(context.resources.getString(R.string.logins_warning_dialog_title_2))
+ setMessage(
+ context.resources.getString(R.string.logins_warning_dialog_message_2),
+ )
+
+ setNegativeButton(context.resources.getString(R.string.logins_warning_dialog_later)) { _: DialogInterface, _ ->
+ onIgnorePinWarning()
+ }
+
+ setPositiveButton(context.resources.getString(R.string.logins_warning_dialog_set_up_now)) { it: DialogInterface, _ ->
+ it.dismiss()
+ val intent = Intent(Settings.ACTION_SECURITY_SETTINGS)
+ context.startActivity(intent)
+ }
+ create().withCenterAlignedButtons()
+ }.show().secure(activity)
+ activity.settings().incrementSecureWarningCount()
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/creditcards/view/CreditCardEditorView.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/creditcards/view/CreditCardEditorView.kt
index f59b6a1f87..b2501cab3f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/creditcards/view/CreditCardEditorView.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/creditcards/view/CreditCardEditorView.kt
@@ -62,12 +62,12 @@ class CreditCardEditorView(
binding.cardNumberLayout.setErrorTextColor(
ColorStateList.valueOf(
- binding.root.context.getColorFromAttr(R.attr.textWarning),
+ binding.root.context.getColorFromAttr(R.attr.textCritical),
),
)
binding.nameOnCardLayout.setErrorTextColor(
ColorStateList.valueOf(
- binding.root.context.getColorFromAttr(R.attr.textWarning),
+ binding.root.context.getColorFromAttr(R.attr.textCritical),
),
)
@@ -128,7 +128,7 @@ class CreditCardEditorView(
binding.cardNumberLayout.error =
binding.root.context.getString(R.string.credit_cards_number_validation_error_message_2)
- binding.cardNumberTitle.setTextColor(binding.root.context.getColorFromAttr(R.attr.textWarning))
+ binding.cardNumberTitle.setTextColor(binding.root.context.getColorFromAttr(R.attr.textCritical))
}
if (binding.nameOnCardInput.text.toString().isNotBlank()) {
@@ -139,7 +139,7 @@ class CreditCardEditorView(
binding.nameOnCardLayout.error =
binding.root.context.getString(R.string.credit_cards_name_on_card_validation_error_message_2)
- binding.nameOnCardTitle.setTextColor(binding.root.context.getColorFromAttr(R.attr.textWarning))
+ binding.nameOnCardTitle.setTextColor(binding.root.context.getColorFromAttr(R.attr.textCritical))
}
return isValid
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
index e1cadea39c..5a85e34302 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
@@ -281,7 +281,7 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
ColorStateList.valueOf(
ContextCompat.getColor(
requireContext(),
- R.color.fx_mobile_text_color_warning,
+ R.color.fx_mobile_text_color_critical,
),
),
)
@@ -295,7 +295,7 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
ColorStateList.valueOf(
ContextCompat.getColor(
requireContext(),
- R.color.fx_mobile_text_color_warning,
+ R.color.fx_mobile_text_color_critical,
),
),
)
@@ -319,7 +319,7 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
layout.setErrorIconDrawable(R.drawable.mozac_ic_warning_with_bottom_padding)
layout.setErrorIconTintList(
ColorStateList.valueOf(
- ContextCompat.getColor(requireContext(), R.color.fx_mobile_text_color_warning),
+ ContextCompat.getColor(requireContext(), R.color.fx_mobile_text_color_critical),
),
)
}
@@ -332,7 +332,7 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
layout.setErrorIconDrawable(R.drawable.mozac_ic_warning_with_bottom_padding)
layout.setErrorIconTintList(
ColorStateList.valueOf(
- ContextCompat.getColor(requireContext(), R.color.fx_mobile_text_color_warning),
+ ContextCompat.getColor(requireContext(), R.color.fx_mobile_text_color_critical),
),
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
index 59b210ae36..5310536b77 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
@@ -273,7 +273,7 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login), MenuProvider {
ColorStateList.valueOf(
ContextCompat.getColor(
requireContext(),
- R.color.fx_mobile_text_color_warning,
+ R.color.fx_mobile_text_color_critical,
),
),
)
@@ -290,7 +290,7 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login), MenuProvider {
layout.setErrorIconDrawable(R.drawable.mozac_ic_warning_with_bottom_padding)
layout.setErrorIconTintList(
ColorStateList.valueOf(
- ContextCompat.getColor(requireContext(), R.color.fx_mobile_text_color_warning),
+ ContextCompat.getColor(requireContext(), R.color.fx_mobile_text_color_critical),
),
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt
index 5b7c0c2d71..f492e70bad 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt
@@ -4,29 +4,16 @@
package org.mozilla.fenix.settings.logins.fragment
-import android.app.KeyguardManager
-import android.content.Context
-import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
-import android.provider.Settings.ACTION_SECURITY_SETTINGS
-import android.view.View
import androidx.activity.result.ActivityResultLauncher
-import androidx.appcompat.app.AlertDialog
-import androidx.core.content.getSystemService
-import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
-import kotlinx.coroutines.Dispatchers.Main
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
import mozilla.components.feature.autofill.preference.AutofillPreference
import mozilla.components.service.fxa.SyncEngine
import mozilla.components.service.glean.private.NoExtras
-import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
-import mozilla.components.ui.widgets.withCenterAlignedButtons
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.R
import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
@@ -34,24 +21,20 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateWithBreadcrumb
import org.mozilla.fenix.ext.registerForActivityResult
import org.mozilla.fenix.ext.requireComponents
-import org.mozilla.fenix.ext.runIfFragmentIsAttached
-import org.mozilla.fenix.ext.secure
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.settings.SharedPreferenceUpdater
import org.mozilla.fenix.settings.SyncPreferenceView
-import org.mozilla.fenix.settings.biometric.BiometricPromptFeature
+import org.mozilla.fenix.settings.biometric.bindBiometricsCredentialsPromptOrShowWarning
import org.mozilla.fenix.settings.requirePreference
@Suppress("TooManyFunctions")
class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
- private val biometricPromptFeature = ViewBoundFeatureWrapper()
- private lateinit var startForResult: ActivityResultLauncher
+ private lateinit var savedLoginsFragmentLauncher: ActivityResultLauncher
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
- startForResult = registerForActivityResult {
+ savedLoginsFragmentLauncher = registerForActivityResult {
navigateToSavedLoginsFragment()
}
}
@@ -71,32 +54,7 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
requirePreference(R.string.pref_key_saved_logins).isEnabled = enabled
}
- private fun navigateToSavedLogins() {
- runIfFragmentIsAttached {
- viewLifecycleOwner.lifecycleScope.launch(Main) {
- // Workaround for likely biometric library bug
- // https://github.com/mozilla-mobile/fenix/issues/8438
- delay(SHORT_DELAY_MS)
- navigateToSavedLoginsFragment()
- }
- }
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- biometricPromptFeature.set(
- feature = BiometricPromptFeature(
- context = requireContext(),
- fragment = this,
- onAuthFailure = { togglePrefsEnabledWhileAuthenticating(true) },
- onAuthSuccess = ::navigateToSavedLogins,
- ),
- owner = this,
- view = view,
- )
- }
-
+ @Suppress("LongMethod")
override fun onResume() {
super.onResume()
showToolbar(getString(R.string.preferences_passwords_logins_and_passwords))
@@ -146,7 +104,17 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
}
requirePreference(R.string.pref_key_saved_logins).setOnPreferenceClickListener {
- verifyCredentialsOrShowSetupWarning(it.context)
+ view?.let { view ->
+ bindBiometricsCredentialsPromptOrShowWarning(
+ view = view,
+ onShowPinVerification = { intent ->
+ savedLoginsFragmentLauncher.launch(intent)
+ },
+ onAuthSuccess = ::navigateToSavedLoginsFragment,
+ onAuthFailure = { togglePrefsEnabledWhileAuthenticating(true) },
+ doWhileAuthenticating = { togglePrefsEnabledWhileAuthenticating(false) },
+ )
+ }
true
}
@@ -178,60 +146,6 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
togglePrefsEnabledWhileAuthenticating(true)
}
- private fun verifyCredentialsOrShowSetupWarning(context: Context) {
- // Use the BiometricPrompt first
- if (BiometricPromptFeature.canUseFeature(context)) {
- togglePrefsEnabledWhileAuthenticating(false)
- biometricPromptFeature.get()
- ?.requestAuthentication(getString(R.string.logins_biometric_prompt_message_2))
- return
- }
-
- // Fallback to prompting for password with the KeyguardManager
- val manager = context.getSystemService()
- if (manager?.isKeyguardSecure == true) {
- showPinVerification(manager)
- } else {
- // Warn that the device has not been secured
- if (context.settings().shouldShowSecurityPinWarning) {
- showPinDialogWarning(context)
- } else {
- navigateToSavedLoginsFragment()
- }
- }
- }
-
- private fun showPinDialogWarning(context: Context) {
- AlertDialog.Builder(context).apply {
- setTitle(getString(R.string.logins_warning_dialog_title_2))
- setMessage(
- getString(R.string.logins_warning_dialog_message_2),
- )
-
- setNegativeButton(getString(R.string.logins_warning_dialog_later)) { _: DialogInterface, _ ->
- navigateToSavedLoginsFragment()
- }
-
- setPositiveButton(getString(R.string.logins_warning_dialog_set_up_now)) { it: DialogInterface, _ ->
- it.dismiss()
- val intent = Intent(ACTION_SECURITY_SETTINGS)
- startActivity(intent)
- }
- create().withCenterAlignedButtons()
- }.show().secure(activity)
- context.settings().incrementSecureWarningCount()
- }
-
- @Suppress("Deprecation")
- private fun showPinVerification(manager: KeyguardManager) {
- val intent = manager.createConfirmDeviceCredentialIntent(
- getString(R.string.logins_biometric_prompt_message_pin),
- getString(R.string.logins_biometric_prompt_message),
- )
-
- startForResult.launch(intent)
- }
-
/**
* Called when authentication succeeds.
*/
@@ -260,9 +174,4 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginExceptionsFragment()
findNavController().navigate(directions)
}
-
- companion object {
- const val SHORT_DELAY_MS = 100L
- const val PIN_REQUEST = 303
- }
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineMenu.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineMenu.kt
index d28867513b..cb1b17788f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineMenu.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineMenu.kt
@@ -40,7 +40,7 @@ class SearchEngineMenu(
items.add(
SimpleBrowserMenuItem(
context.getString(R.string.search_engine_delete),
- textColorResource = ThemeManager.resolveAttribute(R.attr.textWarning, context),
+ textColorResource = ThemeManager.resolveAttribute(R.attr.textCritical, context),
) {
onItemTapped.invoke(Item.Delete)
},
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineShortcuts.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineShortcuts.kt
index 46ca337e42..04d4d90dde 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineShortcuts.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineShortcuts.kt
@@ -198,13 +198,13 @@ private fun SearchItem(
menuItems = listOf(
MenuItem(
stringResource(R.string.search_engine_edit),
- color = FirefoxTheme.colors.textWarning,
+ color = FirefoxTheme.colors.textCritical,
) {
onEditEngineClicked(engine)
},
MenuItem(
stringResource(R.string.search_engine_delete),
- color = FirefoxTheme.colors.textWarning,
+ color = FirefoxTheme.colors.textCritical,
) {
onDeleteEngineClicked(engine)
},
@@ -268,7 +268,7 @@ private fun SearchEngineShortcutsPreview() {
initialState = BrowserState(
search = SearchState(
regionSearchEngines = generateFakeEnginesList(),
- disabledSearchEngineIds = listOf("8", "9"),
+ disabledSearchEngineIds = listOf("7", "8"),
),
),
),
@@ -288,13 +288,12 @@ private fun generateFakeEnginesList(): List {
generateFakeEngines("1", "Google"),
generateFakeEngines("2", "Bing"),
generateFakeEngines("3", "Bing"),
- generateFakeEngines("4", "Amazon.com"),
- generateFakeEngines("5", "DuckDuckGo"),
- generateFakeEngines("6", "Qwant"),
- generateFakeEngines("7", "eBay"),
- generateFakeEngines("8", "Reddit"),
- generateFakeEngines("9", "YouTube"),
- generateFakeEngines("10", "Yandex", SearchEngine.Type.CUSTOM),
+ generateFakeEngines("4", "DuckDuckGo"),
+ generateFakeEngines("5", "Qwant"),
+ generateFakeEngines("6", "eBay"),
+ generateFakeEngines("7", "Reddit"),
+ generateFakeEngines("8", "YouTube"),
+ generateFakeEngines("9", "Yandex", SearchEngine.Type.CUSTOM),
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/SaveToPDFMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/SaveToPDFMiddleware.kt
index 25f28887f4..3e9593851b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/SaveToPDFMiddleware.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/SaveToPDFMiddleware.kt
@@ -16,6 +16,7 @@ import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
+import org.mozilla.experiments.nimbus.NimbusEventStore
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.StandardSnackbarError
@@ -35,10 +36,12 @@ import java.io.IOException
*
* @param context An Application context.
* @param mainScope Coroutine scope to launch coroutines.
+ * @param nimbusEventStore Nimbus event store for recording events.
*/
class SaveToPDFMiddleware(
private val context: Context,
private val mainScope: CoroutineScope = CoroutineScope(Dispatchers.Main),
+ private val nimbusEventStore: NimbusEventStore = context.components.nimbus.events,
) : Middleware {
override fun invoke(
@@ -151,6 +154,7 @@ class SaveToPDFMiddleware(
source = telemetrySource(isPdf),
),
)
+ nimbusEventStore.recordEvent("print_tapped")
} else {
Events.saveToPdfTapped.record(
Events.SaveToPdfTappedExtra(
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckInfoCard.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckInfoCard.kt
index 3fbb9b8d5a..5c033066c7 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckInfoCard.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckInfoCard.kt
@@ -40,19 +40,20 @@ import org.mozilla.fenix.theme.FirefoxTheme
/**
* Review Quality Check Info Card UI.
*
+ * @param modifier Modifier to be applied to the card.
* @param title The primary text of the info message.
* @param type The [ReviewQualityCheckInfoType] of message to display.
- * @param modifier Modifier to be applied to the card.
* @param verticalRowAlignment An optional adjustment of how the row of text aligns.
* @param description The optional secondary piece of text.
* @param footer An optional piece of text with a clickable link.
* @param buttonText The text to show in the optional button.
*/
+@Suppress("LongMethod")
@Composable
fun ReviewQualityCheckInfoCard(
- title: String,
- type: ReviewQualityCheckInfoType,
modifier: Modifier = Modifier,
+ title: String? = null,
+ type: ReviewQualityCheckInfoType,
verticalRowAlignment: Alignment.Vertical = Alignment.Top,
description: String? = null,
footer: Pair? = null,
@@ -67,7 +68,7 @@ fun ReviewQualityCheckInfoCard(
),
elevation = 0.dp,
) {
- val titleContentDescription = headingResource(title)
+ val titleContentDescription = title?.let { headingResource(it) }
Row(
verticalAlignment = verticalRowAlignment,
@@ -81,7 +82,10 @@ fun ReviewQualityCheckInfoCard(
InfoCardIcon(iconId = R.drawable.mozac_ic_checkmark_24)
}
- ReviewQualityCheckInfoType.Error,
+ ReviewQualityCheckInfoType.Error -> {
+ InfoCardIcon(iconId = R.drawable.mozac_ic_critical_fill_24)
+ }
+
ReviewQualityCheckInfoType.Info,
ReviewQualityCheckInfoType.AnalysisUpdate,
-> {
@@ -92,18 +96,22 @@ fun ReviewQualityCheckInfoCard(
Spacer(modifier = Modifier.width(12.dp))
Column {
- Text(
- text = title,
- color = FirefoxTheme.colors.textPrimary,
- style = FirefoxTheme.typography.headline8,
- modifier = Modifier.semantics {
- heading()
- contentDescription = titleContentDescription
- },
- )
+ title?.let {
+ Text(
+ text = it,
+ color = FirefoxTheme.colors.textPrimary,
+ style = FirefoxTheme.typography.headline8,
+ modifier = Modifier.semantics {
+ heading()
+ if (titleContentDescription != null) {
+ contentDescription = titleContentDescription
+ }
+ },
+ )
+ }
description?.let {
- Spacer(modifier = Modifier.height(4.dp))
+ title?.let { Spacer(modifier = Modifier.height(4.dp)) }
Text(
text = description,
@@ -170,9 +178,9 @@ enum class ReviewQualityCheckInfoType {
@Composable
get() = when (this) {
Warning -> FirefoxTheme.colors.layerWarning
- Confirmation -> FirefoxTheme.colors.layerConfirmation
- Error -> FirefoxTheme.colors.layerError
- Info -> FirefoxTheme.colors.layerInfo
+ Confirmation -> FirefoxTheme.colors.layerSuccess
+ Error -> FirefoxTheme.colors.layerCritical
+ Info -> FirefoxTheme.colors.layerInformation
AnalysisUpdate -> Color.Transparent
}
@@ -180,9 +188,9 @@ enum class ReviewQualityCheckInfoType {
@Composable
get() = when (this) {
Warning -> FirefoxTheme.colors.actionWarning
- Confirmation -> FirefoxTheme.colors.actionConfirmation
- Error -> FirefoxTheme.colors.actionError
- Info -> FirefoxTheme.colors.actionInfo
+ Confirmation -> FirefoxTheme.colors.actionSuccess
+ Error -> FirefoxTheme.colors.actionCritical
+ Info -> FirefoxTheme.colors.actionInformation
AnalysisUpdate -> FirefoxTheme.colors.actionSecondary
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt
index 27336f6343..58b0042c64 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsController.kt
@@ -16,4 +16,9 @@ interface SyncedTabsController {
* @param tab The synced [Tab] that was clicked.
*/
fun handleSyncedTabClicked(tab: Tab)
+
+ /**
+ * Handles a click on the "close" button for a synced tab.
+ */
+ fun handleSyncedTabClosed(deviceId: String, tab: Tab)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt
index 153a0f48d7..f37655bcac 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/SyncedTabsInteractor.kt
@@ -16,4 +16,9 @@ interface SyncedTabsInteractor {
* @param tab The synced [Tab] that was clicked.
*/
fun onSyncedTabClicked(tab: Tab)
+
+ /**
+ * Invoked when the user closes a synced [Tab].
+ */
+ fun onSyncedTabClosed(deviceId: String, tab: Tab)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTray.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTray.kt
index 65909b5261..533a6454df 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTray.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTray.kt
@@ -48,6 +48,8 @@ import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsList
import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsListItem
import org.mozilla.fenix.theme.FirefoxTheme
import mozilla.components.browser.storage.sync.Tab as SyncTab
+import org.mozilla.fenix.tabstray.syncedtabs.OnTabClick as OnSyncedTabClick
+import org.mozilla.fenix.tabstray.syncedtabs.OnTabCloseClick as OnSyncedTabClose
/**
* Top-level UI for displaying the Tabs Tray feature.
@@ -75,6 +77,7 @@ import mozilla.components.browser.storage.sync.Tab as SyncTab
* @param onInactiveTabClick Invoked when the user clicks on an inactive tab.
* @param onInactiveTabClose Invoked when the user clicks on an inactive tab's close button.
* @param onSyncedTabClick Invoked when the user clicks on a synced tab.
+ * @param onSyncedTabClose Invoked when the user clicks on a synced tab's close button.
* @param onSaveToCollectionClick Invoked when the user clicks on the save to collection button from
* the multi select banner.
* @param onShareSelectedTabsClick Invoked when the user clicks on the share button from the
@@ -92,6 +95,10 @@ import mozilla.components.browser.storage.sync.Tab as SyncTab
* @param onTabAutoCloseBannerDismiss Invoked when the user clicks to dismiss the auto close banner.
* @param onTabAutoCloseBannerShown Invoked when the auto close banner has been shown to the user.
* @param onMove Invoked after the drag and drop gesture completed. Swaps positions of two tabs.
+ * @param shouldShowInactiveTabsCFR Returns whether the inactive tabs CFR should be displayed.
+ * @param onInactiveTabsCFRShown Invoked when the inactive tabs CFR is displayed.
+ * @param onInactiveTabsCFRClick Invoked when the inactive tabs CFR is clicked.
+ * @param onInactiveTabsCFRDismiss Invoked when the inactive tabs CFR is dismissed.
*/
@OptIn(ExperimentalFoundationApi::class)
@Suppress("LongMethod", "LongParameterList", "ComplexMethod")
@@ -116,7 +123,8 @@ fun TabsTray(
onEnableInactiveTabAutoCloseClick: () -> Unit,
onInactiveTabClick: (TabSessionState) -> Unit,
onInactiveTabClose: (TabSessionState) -> Unit,
- onSyncedTabClick: (SyncTab) -> Unit,
+ onSyncedTabClick: OnSyncedTabClick,
+ onSyncedTabClose: OnSyncedTabClose,
onSaveToCollectionClick: () -> Unit,
onShareSelectedTabsClick: () -> Unit,
onShareAllTabsClick: () -> Unit,
@@ -132,6 +140,10 @@ fun TabsTray(
onTabAutoCloseBannerDismiss: () -> Unit,
onTabAutoCloseBannerShown: () -> Unit,
onMove: (String, String?, Boolean) -> Unit,
+ shouldShowInactiveTabsCFR: () -> Boolean,
+ onInactiveTabsCFRShown: () -> Unit,
+ onInactiveTabsCFRClick: () -> Unit,
+ onInactiveTabsCFRDismiss: () -> Unit,
) {
val multiselectMode = tabsTrayStore
.observeAsComposableState { state -> state.mode }.value ?: TabsTrayState.Mode.Normal
@@ -210,6 +222,10 @@ fun TabsTray(
onInactiveTabClick = onInactiveTabClick,
onInactiveTabClose = onInactiveTabClose,
onMove = onMove,
+ shouldShowInactiveTabsCFR = shouldShowInactiveTabsCFR,
+ onInactiveTabsCFRShown = onInactiveTabsCFRShown,
+ onInactiveTabsCFRClick = onInactiveTabsCFRClick,
+ onInactiveTabsCFRDismiss = onInactiveTabsCFRDismiss,
)
}
@@ -230,6 +246,7 @@ fun TabsTray(
SyncedTabsPage(
tabsTrayStore = tabsTrayStore,
onTabClick = onSyncedTabClick,
+ onTabClose = onSyncedTabClose,
)
}
}
@@ -258,6 +275,10 @@ private fun NormalTabsPage(
onInactiveTabClick: (TabSessionState) -> Unit,
onInactiveTabClose: (TabSessionState) -> Unit,
onMove: (String, String?, Boolean) -> Unit,
+ shouldShowInactiveTabsCFR: () -> Boolean,
+ onInactiveTabsCFRShown: () -> Unit,
+ onInactiveTabsCFRClick: () -> Unit,
+ onInactiveTabsCFRDismiss: () -> Unit,
) {
val inactiveTabsExpanded = appStore
.observeAsComposableState { state -> state.inactiveTabsExpanded }.value ?: false
@@ -283,6 +304,7 @@ private fun NormalTabsPage(
inactiveTabs = inactiveTabs,
expanded = inactiveTabsExpanded,
showAutoCloseDialog = showAutoCloseDialog,
+ showCFR = shouldShowInactiveTabsCFR(),
onHeaderClick = onInactiveTabsHeaderClick,
onDeleteAllButtonClick = onDeleteAllInactiveTabsClick,
onAutoCloseDismissClick = {
@@ -295,6 +317,9 @@ private fun NormalTabsPage(
},
onTabClick = onInactiveTabClick,
onTabCloseClick = onInactiveTabClose,
+ onCFRShown = onInactiveTabsCFRShown,
+ onCFRClick = onInactiveTabsCFRClick,
+ onCFRDismiss = onInactiveTabsCFRDismiss,
)
}
}
@@ -366,7 +391,8 @@ private fun PrivateTabsPage(
@Composable
private fun SyncedTabsPage(
tabsTrayStore: TabsTrayStore,
- onTabClick: (SyncTab) -> Unit,
+ onTabClick: OnSyncedTabClick,
+ onTabClose: OnSyncedTabClose,
) {
val syncedTabs = tabsTrayStore
.observeAsComposableState { state -> state.syncedTabs }.value ?: emptyList()
@@ -374,6 +400,7 @@ private fun SyncedTabsPage(
SyncedTabsList(
syncedTabs = syncedTabs,
onTabClick = onTabClick,
+ onTabCloseClick = onTabClose,
)
}
@@ -565,6 +592,7 @@ private fun TabsTrayPreviewRoot(
onInactiveTabClick = {},
onInactiveTabClose = inactiveTabsState::remove,
onSyncedTabClick = {},
+ onSyncedTabClose = { _, _ -> },
onSaveToCollectionClick = {},
onShareSelectedTabsClick = {},
onShareAllTabsClick = {},
@@ -580,6 +608,10 @@ private fun TabsTrayPreviewRoot(
onTabAutoCloseBannerDismiss = {},
onTabAutoCloseBannerShown = {},
onMove = { _, _, _ -> },
+ shouldShowInactiveTabsCFR = { false },
+ onInactiveTabsCFRShown = {},
+ onInactiveTabsCFRClick = {},
+ onInactiveTabsCFRDismiss = {},
)
}
}
@@ -607,10 +639,15 @@ private fun generateFakeSyncedTabsList(deviceCount: Int = 1): List Unit,
@@ -520,6 +523,12 @@ class DefaultTabsTrayController(
)
}
+ override fun handleSyncedTabClosed(deviceId: String, tab: Tab) {
+ CoroutineScope(ioDispatcher).launch {
+ closeSyncedTabsUseCases.close(deviceId, tab.active().url)
+ }
+ }
+
override fun handleTabLongClick(tab: TabSessionState): Boolean {
return if (tab.isNormalTab() && tabsTrayStore.state.mode.selectedTabs.isEmpty()) {
Collections.longPress.record(NoExtras())
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt
index fded1b9494..9086708892 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt
@@ -30,6 +30,7 @@ import mozilla.components.browser.state.selector.normalTabs
import mozilla.components.browser.state.selector.privateTabs
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.base.crash.Breadcrumb
+import mozilla.components.feature.accounts.push.CloseTabsUseCases
import mozilla.components.feature.downloads.ui.DownloadCancelDialogFragment
import mozilla.components.feature.tabs.tabstray.TabsFeature
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
@@ -181,6 +182,7 @@ class TabsTrayFragment : AppCompatDialogFragment() {
navigationInteractor = navigationInteractor,
profiler = requireComponents.core.engine.profiler,
tabsUseCases = requireComponents.useCases.tabsUseCases,
+ closeSyncedTabsUseCases = CloseTabsUseCases(requireComponents.backgroundServices.accountManager),
bookmarksUseCase = requireComponents.useCases.bookmarksUseCases,
ioDispatcher = Dispatchers.IO,
collectionStorage = requireComponents.core.tabCollectionStorage,
@@ -275,6 +277,7 @@ class TabsTrayFragment : AppCompatDialogFragment() {
onInactiveTabClick = tabsTrayInteractor::onInactiveTabClicked,
onInactiveTabClose = tabsTrayInteractor::onInactiveTabClosed,
onSyncedTabClick = tabsTrayInteractor::onSyncedTabClicked,
+ onSyncedTabClose = tabsTrayInteractor::onSyncedTabClosed,
onSaveToCollectionClick = tabsTrayInteractor::onAddSelectedTabsToCollectionClicked,
onShareSelectedTabsClick = tabsTrayInteractor::onShareSelectedTabs,
onShareAllTabsClick = {
@@ -307,6 +310,23 @@ class TabsTrayFragment : AppCompatDialogFragment() {
requireContext().settings().lastCfrShownTimeInMillis = System.currentTimeMillis()
},
onMove = tabsTrayInteractor::onTabsMove,
+ shouldShowInactiveTabsCFR = {
+ requireContext().settings().shouldShowInactiveTabsOnboardingPopup &&
+ requireContext().settings().canShowCfr
+ },
+ onInactiveTabsCFRShown = {
+ TabsTray.inactiveTabsCfrVisible.record(NoExtras())
+ },
+ onInactiveTabsCFRClick = {
+ requireContext().settings().shouldShowInactiveTabsOnboardingPopup = false
+ navigationInteractor.onTabSettingsClicked()
+ TabsTray.inactiveTabsCfrSettings.record(NoExtras())
+ onTabsTrayDismissed()
+ },
+ onInactiveTabsCFRDismiss = {
+ requireContext().settings().shouldShowInactiveTabsOnboardingPopup = false
+ TabsTray.inactiveTabsCfrDismissed.record(NoExtras())
+ },
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt
index b9f8bb5473..e29aafc793 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayInteractor.kt
@@ -157,6 +157,10 @@ class DefaultTabsTrayInteractor(
controller.handleSyncedTabClicked(tab)
}
+ override fun onSyncedTabClosed(deviceId: String, tab: Tab) {
+ controller.handleSyncedTabClosed(deviceId, tab)
+ }
+
override fun onBackPressed(): Boolean = controller.handleBackPressed()
override fun onTabClosed(tab: TabSessionState, source: String?) {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt
index 6980806179..945cacd5be 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabViewHolder.kt
@@ -60,6 +60,7 @@ class InactiveTabViewHolder(
inactiveTabs = inactiveTabs,
expanded = expanded,
showAutoCloseDialog = showAutoClosePrompt,
+ showCFR = false, // The CFR in XML is handled by [TabsTrayInactiveTabsOnboardingBinding]
onHeaderClick = { interactor.onInactiveTabsHeaderClicked(!expanded) },
onDeleteAllButtonClick = interactor::onDeleteAllInactiveTabsClicked,
onAutoCloseDismissClick = {
@@ -73,6 +74,9 @@ class InactiveTabViewHolder(
},
onTabClick = interactor::onInactiveTabClicked,
onTabCloseClick = interactor::onInactiveTabClosed,
+ onCFRShown = {},
+ onCFRClick = {},
+ onCFRDismiss = {},
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsTouchHelper.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsTouchHelper.kt
index b9d762f2f9..37ac921e0f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsTouchHelper.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsTouchHelper.kt
@@ -92,7 +92,7 @@ class TouchCallback(
val icon = recyclerView.context.getDrawableWithTint(
R.drawable.ic_delete,
- recyclerView.context.getColorFromAttr(R.attr.textWarning),
+ recyclerView.context.getColorFromAttr(R.attr.textCritical),
)!!
val background = AppCompatResources.getDrawable(
recyclerView.context,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/ext/SyncedDeviceTabs.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/ext/SyncedDeviceTabs.kt
index 39462fa9b0..c8654eac3f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/ext/SyncedDeviceTabs.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/ext/SyncedDeviceTabs.kt
@@ -5,22 +5,41 @@
package org.mozilla.fenix.tabstray.ext
import mozilla.components.browser.storage.sync.SyncedDeviceTabs
+import mozilla.components.concept.sync.DeviceCapability
import mozilla.components.support.ktx.kotlin.trimmed
import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsListItem
+import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsListSupportedFeature
/**
* Converts a list of [SyncedDeviceTabs] into a list of [SyncedTabsListItem].
+ *
+ * @param features Supported [SyncedTabsListSupportedFeature]s.
*/
-fun List.toComposeList(): List = asSequence().flatMap { (device, tabs) ->
- val deviceTabs = if (tabs.isEmpty()) {
- emptyList()
- } else {
- tabs.map {
- val url = it.active().url
- val titleText = it.active().title.ifEmpty { url.trimmed() }
- SyncedTabsListItem.Tab(titleText, url, it)
+fun List.toComposeList(
+ features: Set = emptySet(),
+): List =
+ asSequence().flatMap { (device, tabs) ->
+ val deviceTabs = if (tabs.isEmpty()) {
+ emptyList()
+ } else {
+ tabs.map {
+ val url = it.active().url
+ val titleText = it.active().title.ifEmpty { url.trimmed() }
+ SyncedTabsListItem.Tab(
+ displayTitle = titleText,
+ displayURL = url,
+ action = if (
+ features.contains(SyncedTabsListSupportedFeature.CLOSE_TABS) &&
+ device.capabilities.contains(DeviceCapability.CLOSE_TABS)
+ ) {
+ SyncedTabsListItem.Tab.Action.Close(deviceId = device.id)
+ } else {
+ SyncedTabsListItem.Tab.Action.None
+ },
+ tab = it,
+ )
+ }
}
- }
- sequenceOf(SyncedTabsListItem.DeviceSection(device.displayName, deviceTabs))
-}.toList()
+ sequenceOf(SyncedTabsListItem.DeviceSection(device.displayName, deviceTabs))
+ }.toList()
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/inactivetabs/InactiveTabs.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/inactivetabs/InactiveTabs.kt
index 27ad2c1b6c..0fbe3941f8 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/inactivetabs/InactiveTabs.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/inactivetabs/InactiveTabs.kt
@@ -6,9 +6,9 @@
package org.mozilla.fenix.tabstray.inactivetabs
-import android.content.res.Configuration
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -31,14 +31,19 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import mozilla.components.browser.state.state.ContentState
import mozilla.components.browser.state.state.TabSessionState
+import mozilla.components.compose.cfr.CFRPopup
+import mozilla.components.compose.cfr.CFRPopupLayout
+import mozilla.components.compose.cfr.CFRPopupProperties
import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.button.TextButton
import org.mozilla.fenix.compose.list.ExpandableListHeader
import org.mozilla.fenix.compose.list.FaviconListItem
@@ -54,12 +59,16 @@ private val ROUNDED_CORNER_SHAPE = RoundedCornerShape(8.dp)
* @param inactiveTabs List of [TabSessionState] to display.
* @param expanded Whether to show the inactive tabs section expanded or collapsed.
* @param showAutoCloseDialog Whether to show the auto close inactive tabs dialog.
+ * @param showCFR Whether to show the CFR.
* @param onHeaderClick Called when the user clicks on the inactive tabs section header.
* @param onDeleteAllButtonClick Called when the user clicks on the delete all inactive tabs button.
* @param onAutoCloseDismissClick Called when the user clicks on the auto close dialog's dismiss button.
* @param onEnableAutoCloseClick Called when the user clicks on the auto close dialog's enable button.
* @param onTabClick Called when the user clicks on a specific inactive tab.
* @param onTabCloseClick Called when the user clicks on a specific inactive tab's close button.
+ * @param onCFRShown Invoked when the CFR is displayed.
+ * @param onCFRClick Invoked when the CFR is clicked.
+ * @param onCFRDismiss Invoked when the CFR is dismissed.
*/
@Composable
@Suppress("LongParameterList")
@@ -67,12 +76,16 @@ fun InactiveTabsList(
inactiveTabs: List,
expanded: Boolean,
showAutoCloseDialog: Boolean,
+ showCFR: Boolean,
onHeaderClick: (Boolean) -> Unit,
onDeleteAllButtonClick: () -> Unit,
onAutoCloseDismissClick: () -> Unit,
onEnableAutoCloseClick: () -> Unit,
onTabClick: (TabSessionState) -> Unit,
onTabCloseClick: (TabSessionState) -> Unit,
+ onCFRShown: () -> Unit,
+ onCFRClick: () -> Unit,
+ onCFRDismiss: () -> Unit,
) {
Card(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
@@ -88,6 +101,10 @@ fun InactiveTabsList(
) {
InactiveTabsHeader(
expanded = expanded,
+ showCFR = showCFR,
+ onCFRShown = onCFRShown,
+ onCFRClick = onCFRClick,
+ onCFRDismiss = onCFRDismiss,
onClick = { onHeaderClick(!expanded) },
onDeleteAllClick = onDeleteAllButtonClick,
)
@@ -128,35 +145,84 @@ fun InactiveTabsList(
}
/**
- * Collapsible header for the Inactive Tabs section.
+ * Collapsible header for the Inactive Tabs section with a CFR.
*
* @param expanded Whether the section is expanded.
+ * @param showCFR Whether to show the CFR.
* @param onClick Called when the user clicks on the header.
* @param onDeleteAllClick Called when the user clicks on the delete all button.
+ * @param onCFRShown Invoked when the CFR is displayed.
+ * @param onCFRClick Invoked when the CFR is clicked.
+ * @param onCFRDismiss Invoked when the CFR is dismissed.
*/
@Composable
private fun InactiveTabsHeader(
expanded: Boolean,
+ showCFR: Boolean,
onClick: () -> Unit,
onDeleteAllClick: () -> Unit,
+ onCFRShown: () -> Unit,
+ onCFRClick: () -> Unit,
+ onCFRDismiss: () -> Unit,
) {
- ExpandableListHeader(
- headerText = stringResource(R.string.inactive_tabs_title),
- headerTextStyle = FirefoxTheme.typography.headline7,
- expanded = expanded,
- expandActionContentDescription = stringResource(R.string.inactive_tabs_expand_content_description),
- collapseActionContentDescription = stringResource(R.string.inactive_tabs_collapse_content_description),
- onClick = onClick,
+ CFRPopupLayout(
+ showCFR = showCFR,
+ properties = CFRPopupProperties(
+ popupBodyColors = listOf(
+ FirefoxTheme.colors.layerGradientEnd.toArgb(),
+ FirefoxTheme.colors.layerGradientStart.toArgb(),
+ ),
+ dismissButtonColor = FirefoxTheme.colors.iconOnColor.toArgb(),
+ indicatorDirection = CFRPopup.IndicatorDirection.UP,
+ popupVerticalOffset = (-12).dp,
+ dismissOnBackPress = true,
+ dismissOnClickOutside = false,
+ ),
+ onCFRShown = onCFRShown,
+ onDismiss = { onCFRDismiss() },
+ text = {
+ FirefoxTheme {
+ Text(
+ text = stringResource(R.string.tab_tray_inactive_onboarding_message),
+ color = FirefoxTheme.colors.textOnColorPrimary,
+ style = FirefoxTheme.typography.body2,
+ )
+ }
+ },
+ action = { dismissCFR ->
+ FirefoxTheme {
+ Text(
+ text = stringResource(R.string.tab_tray_inactive_onboarding_button_text),
+ color = FirefoxTheme.colors.textOnColorPrimary,
+ modifier = Modifier.clickable {
+ dismissCFR()
+ onCFRClick()
+ },
+ style = FirefoxTheme.typography.body2.copy(
+ textDecoration = TextDecoration.Underline,
+ ),
+ )
+ }
+ },
) {
- IconButton(
- onClick = onDeleteAllClick,
- modifier = Modifier.padding(horizontal = 4.dp),
+ ExpandableListHeader(
+ headerText = stringResource(R.string.inactive_tabs_title),
+ headerTextStyle = FirefoxTheme.typography.headline7,
+ expanded = expanded,
+ expandActionContentDescription = stringResource(R.string.inactive_tabs_expand_content_description),
+ collapseActionContentDescription = stringResource(R.string.inactive_tabs_collapse_content_description),
+ onClick = onClick,
) {
- Icon(
- painter = painterResource(R.drawable.ic_delete),
- contentDescription = stringResource(R.string.inactive_tabs_delete_all),
- tint = FirefoxTheme.colors.iconPrimary,
- )
+ IconButton(
+ onClick = onDeleteAllClick,
+ modifier = Modifier.padding(horizontal = 4.dp),
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.ic_delete),
+ contentDescription = stringResource(R.string.inactive_tabs_delete_all),
+ tint = FirefoxTheme.colors.iconPrimary,
+ )
+ }
}
}
}
@@ -229,8 +295,7 @@ private fun InactiveTabsAutoClosePrompt(
}
@Composable
-@Preview(name = "Auto close dialog dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
-@Preview(name = "Auto close dialog light", uiMode = Configuration.UI_MODE_NIGHT_NO)
+@LightDarkPreview
private fun InactiveTabsAutoClosePromptPreview() {
FirefoxTheme {
Box(Modifier.background(FirefoxTheme.colors.layer1)) {
@@ -243,8 +308,7 @@ private fun InactiveTabsAutoClosePromptPreview() {
}
@Composable
-@Preview(name = "Full preview dark", uiMode = Configuration.UI_MODE_NIGHT_YES)
-@Preview(name = "Full preview light", uiMode = Configuration.UI_MODE_NIGHT_NO)
+@LightDarkPreview
private fun InactiveTabsListPreview() {
var expanded by remember { mutableStateOf(true) }
var showAutoClosePrompt by remember { mutableStateOf(true) }
@@ -255,12 +319,16 @@ private fun InactiveTabsListPreview() {
inactiveTabs = generateFakeInactiveTabsList(),
expanded = expanded,
showAutoCloseDialog = showAutoClosePrompt,
+ showCFR = false,
onHeaderClick = { expanded = !expanded },
onDeleteAllButtonClick = {},
onAutoCloseDismissClick = { showAutoClosePrompt = !showAutoClosePrompt },
onEnableAutoCloseClick = { showAutoClosePrompt = !showAutoClosePrompt },
onTabClick = {},
onTabCloseClick = {},
+ onCFRShown = {},
+ onCFRClick = {},
+ onCFRDismiss = {},
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabs.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabs.kt
deleted file mode 100644
index fe39760447..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabs.kt
+++ /dev/null
@@ -1,314 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@file:Suppress("TooManyFunctions")
-
-package org.mozilla.fenix.tabstray.syncedtabs
-
-import android.content.res.Configuration
-import androidx.annotation.VisibleForTesting
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.IntrinsicSize
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.lazy.rememberLazyListState
-import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.toMutableStateList
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import mozilla.components.browser.storage.sync.TabEntry
-import mozilla.components.feature.syncedtabs.view.SyncedTabsView
-import org.mozilla.fenix.R
-import org.mozilla.fenix.compose.Divider
-import org.mozilla.fenix.compose.button.PrimaryButton
-import org.mozilla.fenix.compose.ext.dashedBorder
-import org.mozilla.fenix.compose.list.ExpandableListHeader
-import org.mozilla.fenix.compose.list.FaviconListItem
-import org.mozilla.fenix.tabstray.TabsTrayTestTag
-import org.mozilla.fenix.theme.FirefoxTheme
-import mozilla.components.browser.storage.sync.Tab as SyncTab
-
-private const val EXPANDED_BY_DEFAULT = true
-
-/**
- * Top-level list UI for displaying Synced Tabs in the Tabs Tray.
- *
- * @param syncedTabs The tab UI items to be displayed.
- * @param onTabClick The lambda for handling clicks on synced tabs.
- */
-@SuppressWarnings("LongMethod")
-@OptIn(ExperimentalFoundationApi::class)
-@Composable
-fun SyncedTabsList(
- syncedTabs: List,
- onTabClick: (SyncTab) -> Unit,
-) {
- val listState = rememberLazyListState()
- val expandedState =
- remember(syncedTabs) { syncedTabs.map { EXPANDED_BY_DEFAULT }.toMutableStateList() }
-
- LazyColumn(
- modifier = Modifier
- .fillMaxSize()
- .testTag(TabsTrayTestTag.syncedTabsList),
- state = listState,
- ) {
- syncedTabs.forEachIndexed { index, syncedTabItem ->
- when (syncedTabItem) {
- is SyncedTabsListItem.DeviceSection -> {
- val sectionExpanded = expandedState[index]
-
- stickyHeader {
- SyncedTabsSectionHeader(
- headerText = syncedTabItem.displayName,
- expanded = sectionExpanded,
- ) {
- expandedState[index] = !sectionExpanded
- }
- }
-
- if (sectionExpanded) {
- if (syncedTabItem.tabs.isNotEmpty()) {
- items(syncedTabItem.tabs) { syncedTab ->
- FaviconListItem(
- label = syncedTab.displayTitle,
- description = syncedTab.displayURL,
- url = syncedTab.displayURL,
- onClick = { onTabClick(syncedTab.tab) },
- )
- }
- } else {
- item { SyncedTabsNoTabsItem() }
- }
- }
- }
-
- is SyncedTabsListItem.Error -> {
- item {
- SyncedTabsErrorItem(
- errorText = syncedTabItem.errorText,
- errorButton = syncedTabItem.errorButton,
- )
- }
- }
- else -> {
- // no-op
- }
- }
- }
-
- item {
- // The Spacer here is to act as a footer to add padding to the bottom of the list so
- // the FAB or any potential SnackBar doesn't overlap with the items at the end.
- Spacer(modifier = Modifier.height(240.dp))
- }
- }
-}
-
-/**
- * Collapsible header for sections of synced tabs
- *
- * @param headerText The section title for a group of synced tabs.
- * @param expanded Indicates whether the section of content is expanded. If null, the Icon will be hidden.
- * @param onClick Optional lambda for handling section header clicks.
- */
-@Composable
-fun SyncedTabsSectionHeader(
- headerText: String,
- expanded: Boolean? = null,
- onClick: () -> Unit = {},
-) {
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .background(FirefoxTheme.colors.layer1),
- ) {
- ExpandableListHeader(
- headerText = headerText,
- expanded = expanded,
- expandActionContentDescription = stringResource(R.string.synced_tabs_expand_group),
- collapseActionContentDescription = stringResource(R.string.synced_tabs_collapse_group),
- onClick = onClick,
- )
-
- Divider()
- }
-}
-
-/**
- * Error UI to show if there is one of the errors outlined in [SyncedTabsView.ErrorType].
- *
- * @param errorText The text to be displayed to the user.
- * @param errorButton Optional class to set up and handle any clicks in the Error UI.
- */
-@Composable
-fun SyncedTabsErrorItem(
- errorText: String,
- errorButton: SyncedTabsListItem.ErrorButton? = null,
-) {
- Box(
- Modifier
- .padding(all = 8.dp)
- .height(IntrinsicSize.Min)
- .dashedBorder(
- color = FirefoxTheme.colors.borderPrimary,
- cornerRadius = 8.dp,
- dashHeight = 2.dp,
- dashWidth = 4.dp,
- ),
- ) {
- Column(
- Modifier
- .padding(all = 16.dp)
- .fillMaxWidth(),
- ) {
- Text(
- text = errorText,
- color = FirefoxTheme.colors.textPrimary,
- modifier = Modifier.fillMaxWidth(),
- fontSize = 14.sp,
- )
-
- errorButton?.let {
- Spacer(modifier = Modifier.height(12.dp))
-
- PrimaryButton(
- text = it.buttonText,
- icon = painterResource(R.drawable.ic_sign_in),
- onClick = it.onClick,
- )
- }
- }
- }
-}
-
-/**
- * UI to be displayed when a user's device has no synced tabs.
- */
-@Composable
-fun SyncedTabsNoTabsItem() {
- Text(
- text = stringResource(R.string.synced_tabs_no_open_tabs),
- color = FirefoxTheme.colors.textSecondary,
- modifier = Modifier
- .padding(horizontal = 16.dp, vertical = 8.dp)
- .fillMaxWidth(),
- fontSize = 16.sp,
- maxLines = 1,
- )
-}
-
-@Composable
-@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
-private fun SyncedTabsListItemsPreview() {
- FirefoxTheme {
- Column(Modifier.background(FirefoxTheme.colors.layer1)) {
- SyncedTabsSectionHeader(headerText = "Google Pixel Pro Max +Ultra 5000")
-
- Spacer(modifier = Modifier.height(16.dp))
-
- SyncedTabsSectionHeader(
- headerText = "Collapsible Google Pixel Pro Max +Ultra 5000",
- expanded = true,
- ) { println("Clicked section header") }
-
- Spacer(modifier = Modifier.height(16.dp))
-
- FaviconListItem(
- label = "Mozilla",
- description = "www.mozilla.org",
- url = "www.mozilla.org",
- onClick = {},
- )
-
- Spacer(modifier = Modifier.height(16.dp))
-
- SyncedTabsErrorItem(errorText = stringResource(R.string.synced_tabs_reauth))
-
- Spacer(modifier = Modifier.height(16.dp))
-
- SyncedTabsNoTabsItem()
-
- Spacer(modifier = Modifier.height(16.dp))
- }
- }
-}
-
-@Composable
-@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
-private fun SyncedTabsErrorPreview() {
- FirefoxTheme {
- Box(Modifier.background(FirefoxTheme.colors.layer1)) {
- SyncedTabsErrorItem(
- errorText = stringResource(R.string.synced_tabs_no_tabs),
- errorButton = SyncedTabsListItem.ErrorButton(
- buttonText = stringResource(R.string.synced_tabs_sign_in_button),
- ) {
- println("SyncedTabsErrorButton click")
- },
- )
- }
- }
-}
-
-@Composable
-@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
-private fun SyncedTabsListPreview() {
- FirefoxTheme {
- Box(Modifier.background(FirefoxTheme.colors.layer1)) {
- SyncedTabsList(
- syncedTabs = getFakeSyncedTabList(),
- ) {
- println("Tab clicked")
- }
- }
- }
-}
-
-/**
- * Helper function to create a List of [SyncedTabsListItem] for previewing.
- */
-@VisibleForTesting
-internal fun getFakeSyncedTabList(): List = listOf(
- SyncedTabsListItem.DeviceSection(
- displayName = "Device 1",
- tabs = listOf(
- generateFakeTab("Mozilla", "www.mozilla.org"),
- generateFakeTab("Google", "www.google.com"),
- generateFakeTab("", "www.google.com"),
- ),
- ),
- SyncedTabsListItem.DeviceSection("Device 2", emptyList()),
- SyncedTabsListItem.Error("Please re-authenticate"),
-)
-
-/**
- * Helper function to create a [SyncedTabsListItem.Tab] for previewing.
- */
-private fun generateFakeTab(tabName: String, tabUrl: String): SyncedTabsListItem.Tab =
- SyncedTabsListItem.Tab(
- tabName.ifEmpty { tabUrl },
- tabUrl,
- SyncTab(
- history = listOf(TabEntry(tabName, tabUrl, null)),
- active = 0,
- lastUsed = 0L,
- inactive = false,
- ),
- )
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsIntegration.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsIntegration.kt
index 2bc7814e53..9dc0a2246f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsIntegration.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsIntegration.kt
@@ -15,6 +15,7 @@ import mozilla.components.service.fxa.manager.FxaAccountManager
import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.base.observer.Observable
import mozilla.components.support.base.observer.ObserverRegistry
+import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.tabstray.FloatingActionButtonBinding
import org.mozilla.fenix.tabstray.TabsTrayAction
import org.mozilla.fenix.tabstray.TabsTrayStore
@@ -91,7 +92,13 @@ class SyncedTabsIntegration(
override fun displaySyncedTabs(syncedTabs: List) {
store.dispatch(
TabsTrayAction.UpdateSyncedTabs(
- syncedTabs.toComposeList(),
+ syncedTabs.toComposeList(
+ buildSet {
+ if (context.settings().enableCloseSyncedTabs) {
+ add(SyncedTabsListSupportedFeature.CLOSE_TABS)
+ }
+ },
+ ),
),
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsList.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsList.kt
new file mode 100644
index 0000000000..42e8799697
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsList.kt
@@ -0,0 +1,348 @@
+/* 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/. */
+
+@file:Suppress("TooManyFunctions")
+
+package org.mozilla.fenix.tabstray.syncedtabs
+
+import android.content.res.Configuration
+import androidx.annotation.VisibleForTesting
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.toMutableStateList
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import mozilla.components.browser.storage.sync.TabEntry
+import mozilla.components.feature.syncedtabs.view.SyncedTabsView
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.Divider
+import org.mozilla.fenix.compose.button.PrimaryButton
+import org.mozilla.fenix.compose.ext.dashedBorder
+import org.mozilla.fenix.compose.list.ExpandableListHeader
+import org.mozilla.fenix.compose.list.FaviconListItem
+import org.mozilla.fenix.tabstray.TabsTrayTestTag
+import org.mozilla.fenix.theme.FirefoxTheme
+import mozilla.components.browser.storage.sync.Tab as SyncTab
+
+private const val EXPANDED_BY_DEFAULT = true
+
+/**
+ * A lambda invoked when the user clicks on a synced tab in the [SyncedTabsList].
+ */
+typealias OnTabClick = (tab: SyncTab) -> Unit
+
+/**
+ * A lambda invoked when the user clicks a synced tab's close button in the [SyncedTabsList].
+ */
+typealias OnTabCloseClick = (deviceId: String, tab: SyncTab) -> Unit
+
+/**
+ * Top-level list UI for displaying Synced Tabs in the Tabs Tray.
+ *
+ * @param syncedTabs The tab UI items to be displayed.
+ * @param onTabClick The lambda for handling clicks on synced tabs.
+ * @param onTabCloseClick The lambda for handling clicks on a synced tab's close button.
+ */
+@SuppressWarnings("LongMethod")
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+fun SyncedTabsList(
+ syncedTabs: List,
+ onTabClick: OnTabClick,
+ onTabCloseClick: OnTabCloseClick,
+) {
+ val listState = rememberLazyListState()
+ val expandedState =
+ remember(syncedTabs) { syncedTabs.map { EXPANDED_BY_DEFAULT }.toMutableStateList() }
+
+ LazyColumn(
+ modifier = Modifier
+ .fillMaxSize()
+ .testTag(TabsTrayTestTag.syncedTabsList),
+ state = listState,
+ ) {
+ syncedTabs.forEachIndexed { index, syncedTabItem ->
+ when (syncedTabItem) {
+ is SyncedTabsListItem.DeviceSection -> {
+ val sectionExpanded = expandedState[index]
+
+ stickyHeader {
+ SyncedTabsSectionHeader(
+ headerText = syncedTabItem.displayName,
+ expanded = sectionExpanded,
+ ) {
+ expandedState[index] = !sectionExpanded
+ }
+ }
+
+ if (sectionExpanded) {
+ if (syncedTabItem.tabs.isNotEmpty()) {
+ items(syncedTabItem.tabs) { syncedTab ->
+ when (syncedTab.action) {
+ is SyncedTabsListItem.Tab.Action.Close -> FaviconListItem(
+ label = syncedTab.displayTitle,
+ description = syncedTab.displayURL,
+ url = syncedTab.displayURL,
+ onClick = { onTabClick(syncedTab.tab) },
+ iconPainter = painterResource(R.drawable.ic_close),
+ onIconClick = { onTabCloseClick(syncedTab.action.deviceId, syncedTab.tab) },
+ )
+ is SyncedTabsListItem.Tab.Action.None -> FaviconListItem(
+ label = syncedTab.displayTitle,
+ description = syncedTab.displayURL,
+ url = syncedTab.displayURL,
+ onClick = { onTabClick(syncedTab.tab) },
+ )
+ }
+ }
+ } else {
+ item { SyncedTabsNoTabsItem() }
+ }
+ }
+ }
+
+ is SyncedTabsListItem.Error -> {
+ item {
+ SyncedTabsErrorItem(
+ errorText = syncedTabItem.errorText,
+ errorButton = syncedTabItem.errorButton,
+ )
+ }
+ }
+ else -> {
+ // no-op
+ }
+ }
+ }
+
+ item {
+ // The Spacer here is to act as a footer to add padding to the bottom of the list so
+ // the FAB or any potential SnackBar doesn't overlap with the items at the end.
+ Spacer(modifier = Modifier.height(240.dp))
+ }
+ }
+}
+
+/**
+ * Collapsible header for sections of synced tabs
+ *
+ * @param headerText The section title for a group of synced tabs.
+ * @param expanded Indicates whether the section of content is expanded. If null, the Icon will be hidden.
+ * @param onClick Optional lambda for handling section header clicks.
+ */
+@Composable
+fun SyncedTabsSectionHeader(
+ headerText: String,
+ expanded: Boolean? = null,
+ onClick: () -> Unit = {},
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(FirefoxTheme.colors.layer1),
+ ) {
+ ExpandableListHeader(
+ headerText = headerText,
+ expanded = expanded,
+ expandActionContentDescription = stringResource(R.string.synced_tabs_expand_group),
+ collapseActionContentDescription = stringResource(R.string.synced_tabs_collapse_group),
+ onClick = onClick,
+ )
+
+ Divider()
+ }
+}
+
+/**
+ * Error UI to show if there is one of the errors outlined in [SyncedTabsView.ErrorType].
+ *
+ * @param errorText The text to be displayed to the user.
+ * @param errorButton Optional class to set up and handle any clicks in the Error UI.
+ */
+@Composable
+fun SyncedTabsErrorItem(
+ errorText: String,
+ errorButton: SyncedTabsListItem.ErrorButton? = null,
+) {
+ Box(
+ Modifier
+ .padding(all = 8.dp)
+ .height(IntrinsicSize.Min)
+ .dashedBorder(
+ color = FirefoxTheme.colors.borderPrimary,
+ cornerRadius = 8.dp,
+ dashHeight = 2.dp,
+ dashWidth = 4.dp,
+ ),
+ ) {
+ Column(
+ Modifier
+ .padding(all = 16.dp)
+ .fillMaxWidth(),
+ ) {
+ Text(
+ text = errorText,
+ color = FirefoxTheme.colors.textPrimary,
+ modifier = Modifier.fillMaxWidth(),
+ fontSize = 14.sp,
+ )
+
+ errorButton?.let {
+ Spacer(modifier = Modifier.height(12.dp))
+
+ PrimaryButton(
+ text = it.buttonText,
+ icon = painterResource(R.drawable.ic_sign_in),
+ onClick = it.onClick,
+ )
+ }
+ }
+ }
+}
+
+/**
+ * UI to be displayed when a user's device has no synced tabs.
+ */
+@Composable
+fun SyncedTabsNoTabsItem() {
+ Text(
+ text = stringResource(R.string.synced_tabs_no_open_tabs),
+ color = FirefoxTheme.colors.textSecondary,
+ modifier = Modifier
+ .padding(horizontal = 16.dp, vertical = 8.dp)
+ .fillMaxWidth(),
+ fontSize = 16.sp,
+ maxLines = 1,
+ )
+}
+
+@Composable
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun SyncedTabsListItemsPreview() {
+ FirefoxTheme {
+ Column(Modifier.background(FirefoxTheme.colors.layer1)) {
+ SyncedTabsSectionHeader(headerText = "Google Pixel Pro Max +Ultra 5000")
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ SyncedTabsSectionHeader(
+ headerText = "Collapsible Google Pixel Pro Max +Ultra 5000",
+ expanded = true,
+ ) { println("Clicked section header") }
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ FaviconListItem(
+ label = "Mozilla",
+ description = "www.mozilla.org",
+ url = "www.mozilla.org",
+ onClick = {},
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ SyncedTabsErrorItem(errorText = stringResource(R.string.synced_tabs_reauth))
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ SyncedTabsNoTabsItem()
+
+ Spacer(modifier = Modifier.height(16.dp))
+ }
+ }
+}
+
+@Composable
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun SyncedTabsErrorPreview() {
+ FirefoxTheme {
+ Box(Modifier.background(FirefoxTheme.colors.layer1)) {
+ SyncedTabsErrorItem(
+ errorText = stringResource(R.string.synced_tabs_no_tabs),
+ errorButton = SyncedTabsListItem.ErrorButton(
+ buttonText = stringResource(R.string.synced_tabs_sign_in_button),
+ ) {
+ println("SyncedTabsErrorButton click")
+ },
+ )
+ }
+ }
+}
+
+@Composable
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun SyncedTabsListPreview() {
+ FirefoxTheme {
+ Box(Modifier.background(FirefoxTheme.colors.layer1)) {
+ SyncedTabsList(
+ syncedTabs = getFakeSyncedTabList(),
+ onTabClick = { println("Tab clicked") },
+ onTabCloseClick = { _, _ -> println("Tab closed") },
+ )
+ }
+ }
+}
+
+/**
+ * Helper function to create a List of [SyncedTabsListItem] for previewing.
+ */
+@VisibleForTesting
+internal fun getFakeSyncedTabList(): List = listOf(
+ SyncedTabsListItem.DeviceSection(
+ displayName = "Device 1",
+ tabs = listOf(
+ generateFakeTab("Mozilla", "www.mozilla.org"),
+ generateFakeTab("Google", "www.google.com"),
+ generateFakeTab("", "www.google.com"),
+ ),
+ ),
+ SyncedTabsListItem.DeviceSection(
+ displayName = "Device 2",
+ tabs = listOf(
+ generateFakeTab("Firefox", "www.getfirefox.org", SyncedTabsListItem.Tab.Action.Close("device2222")),
+ generateFakeTab("Thunderbird", "www.getthunderbird.org", SyncedTabsListItem.Tab.Action.Close("device2222")),
+ ),
+ ),
+ SyncedTabsListItem.DeviceSection("Device 3", emptyList()),
+ SyncedTabsListItem.Error("Please re-authenticate"),
+)
+
+/**
+ * Helper function to create a [SyncedTabsListItem.Tab] for previewing.
+ */
+private fun generateFakeTab(
+ tabName: String,
+ tabUrl: String,
+ action: SyncedTabsListItem.Tab.Action = SyncedTabsListItem.Tab.Action.None,
+): SyncedTabsListItem.Tab =
+ SyncedTabsListItem.Tab(
+ tabName.ifEmpty { tabUrl },
+ tabUrl,
+ action,
+ SyncTab(
+ history = listOf(TabEntry(tabName, tabUrl, null)),
+ active = 0,
+ lastUsed = 0L,
+ inactive = false,
+ ),
+ )
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListItem.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListItem.kt
index 186d3192a4..0943187e0b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListItem.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListItem.kt
@@ -31,13 +31,29 @@ sealed class SyncedTabsListItem {
*
* @property displayTitle The title of the tab's web page.
* @property displayURL The tab's URL up to BrowserToolbar.MAX_URI_LENGTH characters long.
+ * @property action The action button to show for this tab.
* @property tab The underlying SyncTab object passed when the tab is clicked.
*/
data class Tab(
val displayTitle: String,
val displayURL: String,
+ val action: Action,
val tab: SyncTab,
- ) : SyncedTabsListItem()
+ ) : SyncedTabsListItem() {
+ /** An action button to show for a [Tab]. */
+ sealed class Action {
+ /**
+ * An action button to close the [Tab] on the synced device.
+ *
+ * @property deviceId The ID of the device on which the [Tab] is
+ * currently open.
+ */
+ data class Close(val deviceId: String) : Action()
+
+ /** A placeholder for a [Tab] without an action button. */
+ data object None : Action()
+ }
+ }
/**
* A placeholder for a device that has no tabs synced.
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListSupportedFeature.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListSupportedFeature.kt
new file mode 100644
index 0000000000..55fac2a78f
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/syncedtabs/SyncedTabsListSupportedFeature.kt
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.tabstray.syncedtabs
+
+/**
+ * Configurable or experimental features that a [SyncedTabsList] supports.
+ */
+enum class SyncedTabsListSupportedFeature {
+ CLOSE_TABS,
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt
index 58ef98f1f1..d6f96723a4 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tabstray/viewholders/SyncedTabsPageViewHolder.kt
@@ -35,6 +35,7 @@ class SyncedTabsPageViewHolder(
SyncedTabsList(
syncedTabs = tabs ?: emptyList(),
onTabClick = interactor::onSyncedTabClicked,
+ onTabCloseClick = interactor::onSyncedTabClosed,
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/theme/FirefoxTheme.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/theme/FirefoxTheme.kt
index 921e989a18..02cff3042f 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/theme/FirefoxTheme.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/theme/FirefoxTheme.kt
@@ -102,19 +102,19 @@ private val darkColorPalette = FirefoxColors(
layerGradientStart = PhotonColors.Violet70,
layerGradientEnd = PhotonColors.Violet40,
layerWarning = PhotonColors.Yellow70A77,
- layerConfirmation = PhotonColors.Green80,
- layerError = PhotonColors.Pink80,
- layerInfo = PhotonColors.Blue50,
+ layerSuccess = PhotonColors.Green80,
+ layerCritical = PhotonColors.Pink80,
+ layerInformation = PhotonColors.Blue50,
layerSearch = PhotonColors.DarkGrey80,
actionPrimary = PhotonColors.Violet60,
actionPrimaryDisabled = PhotonColors.Violet60A50,
- actionSecondary = PhotonColors.LightGrey30,
+ actionSecondary = PhotonColors.DarkGrey05,
actionTertiary = PhotonColors.DarkGrey10,
actionQuarternary = PhotonColors.DarkGrey80,
actionWarning = PhotonColors.Yellow40A41,
- actionConfirmation = PhotonColors.Green70,
- actionError = PhotonColors.Pink70A69,
- actionInfo = PhotonColors.Blue60,
+ actionSuccess = PhotonColors.Green70,
+ actionCritical = PhotonColors.Pink70A69,
+ actionInformation = PhotonColors.Blue60,
formDefault = PhotonColors.LightGrey05,
formSelected = PhotonColors.Violet40,
formSurface = PhotonColors.DarkGrey05,
@@ -126,15 +126,15 @@ private val darkColorPalette = FirefoxColors(
textPrimary = PhotonColors.LightGrey05,
textSecondary = PhotonColors.LightGrey40,
textDisabled = PhotonColors.LightGrey05A40,
- textWarning = PhotonColors.Red20,
- textWarningButton = PhotonColors.Red70,
+ textCritical = PhotonColors.Red20,
+ textCriticalButton = PhotonColors.Red20,
textAccent = PhotonColors.Violet20,
textAccentDisabled = PhotonColors.Violet20A60,
textOnColorPrimary = PhotonColors.LightGrey05,
textOnColorSecondary = PhotonColors.LightGrey40,
textActionPrimary = PhotonColors.LightGrey05,
textActionPrimaryDisabled = PhotonColors.LightGrey05A40,
- textActionSecondary = PhotonColors.DarkGrey90,
+ textActionSecondary = PhotonColors.LightGrey05,
textActionTertiary = PhotonColors.LightGrey05,
textActionTertiaryActive = PhotonColors.LightGrey05,
iconPrimary = PhotonColors.LightGrey05,
@@ -146,15 +146,15 @@ private val darkColorPalette = FirefoxColors(
iconOnColorDisabled = PhotonColors.LightGrey05A40,
iconNotice = PhotonColors.Blue30,
iconButton = PhotonColors.LightGrey05,
- iconWarning = PhotonColors.Red20,
- iconWarningButton = PhotonColors.Red70,
+ iconCritical = PhotonColors.Red20,
+ iconCriticalButton = PhotonColors.Red20,
iconAccentViolet = PhotonColors.Violet20,
iconAccentBlue = PhotonColors.Blue20,
iconAccentPink = PhotonColors.Pink20,
iconAccentGreen = PhotonColors.Green20,
iconAccentYellow = PhotonColors.Yellow20,
iconActionPrimary = PhotonColors.LightGrey05,
- iconActionSecondary = PhotonColors.DarkGrey90,
+ iconActionSecondary = PhotonColors.LightGrey05,
iconActionTertiary = PhotonColors.LightGrey05,
iconGradientStart = PhotonColors.Violet20,
iconGradientEnd = PhotonColors.Blue20,
@@ -164,7 +164,7 @@ private val darkColorPalette = FirefoxColors(
borderFormDefault = PhotonColors.LightGrey05,
borderAccent = PhotonColors.Violet40,
borderDisabled = PhotonColors.LightGrey05A40,
- borderWarning = PhotonColors.Red40,
+ borderCritical = PhotonColors.Red20,
borderToolbarDivider = PhotonColors.DarkGrey60,
)
@@ -182,9 +182,9 @@ private val lightColorPalette = FirefoxColors(
layerGradientStart = PhotonColors.Violet70,
layerGradientEnd = PhotonColors.Violet40,
layerWarning = PhotonColors.Yellow20,
- layerConfirmation = PhotonColors.Green20,
- layerError = PhotonColors.Red10,
- layerInfo = PhotonColors.Blue50A44,
+ layerSuccess = PhotonColors.Green20,
+ layerCritical = PhotonColors.Red10,
+ layerInformation = PhotonColors.Blue50A44,
layerSearch = PhotonColors.LightGrey30,
actionPrimary = PhotonColors.Ink20,
actionPrimaryDisabled = PhotonColors.Ink20A50,
@@ -192,9 +192,9 @@ private val lightColorPalette = FirefoxColors(
actionTertiary = PhotonColors.LightGrey40,
actionQuarternary = PhotonColors.LightGrey10,
actionWarning = PhotonColors.Yellow60A40,
- actionConfirmation = PhotonColors.Green60,
- actionError = PhotonColors.Red30,
- actionInfo = PhotonColors.Blue50,
+ actionSuccess = PhotonColors.Green60,
+ actionCritical = PhotonColors.Red30,
+ actionInformation = PhotonColors.Blue50,
formDefault = PhotonColors.DarkGrey90,
formSelected = PhotonColors.Ink20,
formSurface = PhotonColors.LightGrey50,
@@ -206,8 +206,8 @@ private val lightColorPalette = FirefoxColors(
textPrimary = PhotonColors.DarkGrey90,
textSecondary = PhotonColors.DarkGrey05,
textDisabled = PhotonColors.DarkGrey90A40,
- textWarning = PhotonColors.Red70,
- textWarningButton = PhotonColors.Red70,
+ textCritical = PhotonColors.Red70,
+ textCriticalButton = PhotonColors.Red70,
textAccent = PhotonColors.Violet70,
textAccentDisabled = PhotonColors.Violet70A80,
textOnColorPrimary = PhotonColors.LightGrey05,
@@ -226,9 +226,9 @@ private val lightColorPalette = FirefoxColors(
iconOnColorDisabled = PhotonColors.LightGrey05A40,
iconNotice = PhotonColors.Blue30,
iconButton = PhotonColors.Ink20,
- iconWarning = PhotonColors.Red70,
- iconWarningButton = PhotonColors.Red70,
- iconAccentViolet = PhotonColors.Violet60,
+ iconCritical = PhotonColors.Red70,
+ iconCriticalButton = PhotonColors.Red70,
+ iconAccentViolet = PhotonColors.Violet70,
iconAccentBlue = PhotonColors.Blue60,
iconAccentPink = PhotonColors.Pink60,
iconAccentGreen = PhotonColors.Green60,
@@ -244,15 +244,16 @@ private val lightColorPalette = FirefoxColors(
borderFormDefault = PhotonColors.DarkGrey90,
borderAccent = PhotonColors.Ink20,
borderDisabled = PhotonColors.DarkGrey90A40,
- borderWarning = PhotonColors.Red70,
+ borderCritical = PhotonColors.Red70,
borderToolbarDivider = PhotonColors.LightGrey10,
)
private val privateColorPalette = darkColorPalette.copy(
- layer1 = PhotonColors.Ink50,
- layer2 = PhotonColors.Ink50,
+ layer1 = PhotonColors.Violet90,
+ layer2 = PhotonColors.Violet90,
layer3 = PhotonColors.Ink90,
layerSearch = PhotonColors.Ink90,
+ borderPrimary = PhotonColors.Ink05,
borderSecondary = PhotonColors.Ink10,
borderToolbarDivider = PhotonColors.Violet80,
)
@@ -276,9 +277,9 @@ class FirefoxColors(
layerGradientStart: Color,
layerGradientEnd: Color,
layerWarning: Color,
- layerConfirmation: Color,
- layerError: Color,
- layerInfo: Color,
+ layerSuccess: Color,
+ layerCritical: Color,
+ layerInformation: Color,
layerSearch: Color,
actionPrimary: Color,
actionPrimaryDisabled: Color,
@@ -286,9 +287,9 @@ class FirefoxColors(
actionTertiary: Color,
actionQuarternary: Color,
actionWarning: Color,
- actionConfirmation: Color,
- actionError: Color,
- actionInfo: Color,
+ actionSuccess: Color,
+ actionCritical: Color,
+ actionInformation: Color,
formDefault: Color,
formSelected: Color,
formSurface: Color,
@@ -300,8 +301,8 @@ class FirefoxColors(
textPrimary: Color,
textSecondary: Color,
textDisabled: Color,
- textWarning: Color,
- textWarningButton: Color,
+ textCritical: Color,
+ textCriticalButton: Color,
textAccent: Color,
textAccentDisabled: Color,
textOnColorPrimary: Color,
@@ -320,8 +321,8 @@ class FirefoxColors(
iconOnColorDisabled: Color,
iconNotice: Color,
iconButton: Color,
- iconWarning: Color,
- iconWarningButton: Color,
+ iconCritical: Color,
+ iconCriticalButton: Color,
iconAccentViolet: Color,
iconAccentBlue: Color,
iconAccentPink: Color,
@@ -338,7 +339,7 @@ class FirefoxColors(
borderFormDefault: Color,
borderAccent: Color,
borderDisabled: Color,
- borderWarning: Color,
+ borderCritical: Color,
borderToolbarDivider: Color,
) {
// Layers
@@ -395,15 +396,15 @@ class FirefoxColors(
private set
// Confirmation background
- var layerConfirmation by mutableStateOf(layerConfirmation)
+ var layerSuccess by mutableStateOf(layerSuccess)
private set
// Error Background
- var layerError by mutableStateOf(layerError)
+ var layerCritical by mutableStateOf(layerCritical)
private set
// Info background
- var layerInfo by mutableStateOf(layerInfo)
+ var layerInformation by mutableStateOf(layerInformation)
private set
// Search
@@ -437,15 +438,15 @@ class FirefoxColors(
private set
// Confirmation button
- var actionConfirmation by mutableStateOf(actionConfirmation)
+ var actionSuccess by mutableStateOf(actionSuccess)
private set
// Error button
- var actionError by mutableStateOf(actionError)
+ var actionCritical by mutableStateOf(actionCritical)
private set
// Info button
- var actionInfo by mutableStateOf(actionInfo)
+ var actionInformation by mutableStateOf(actionInformation)
private set
// Checkbox default, Radio button default
@@ -495,11 +496,11 @@ class FirefoxColors(
private set
// Warning text
- var textWarning by mutableStateOf(textWarning)
+ var textCritical by mutableStateOf(textCritical)
private set
// Warning text on Secondary button
- var textWarningButton by mutableStateOf(textWarningButton)
+ var textCriticalButton by mutableStateOf(textCriticalButton)
private set
// Small heading, Text link
@@ -575,11 +576,11 @@ class FirefoxColors(
// Icon button
var iconButton by mutableStateOf(iconButton)
private set
- var iconWarning by mutableStateOf(iconWarning)
+ var iconCritical by mutableStateOf(iconCritical)
private set
// Warning icon on Secondary button
- var iconWarningButton by mutableStateOf(iconWarningButton)
+ var iconCriticalButton by mutableStateOf(iconCriticalButton)
private set
var iconAccentViolet by mutableStateOf(iconAccentViolet)
private set
@@ -638,7 +639,7 @@ class FirefoxColors(
private set
// Form parts
- var borderWarning by mutableStateOf(borderWarning)
+ var borderCritical by mutableStateOf(borderCritical)
private set
// Toolbar divider
@@ -663,9 +664,9 @@ class FirefoxColors(
layerGradientStart = other.layerGradientStart
layerGradientEnd = other.layerGradientEnd
layerWarning = other.layerWarning
- layerConfirmation = other.layerConfirmation
- layerError = other.layerError
- layerInfo = other.layerInfo
+ layerSuccess = other.layerSuccess
+ layerCritical = other.layerCritical
+ layerInformation = other.layerInformation
layerSearch = other.layerSearch
actionPrimary = other.actionPrimary
actionPrimaryDisabled = other.actionPrimaryDisabled
@@ -673,9 +674,9 @@ class FirefoxColors(
actionTertiary = other.actionTertiary
actionQuarternary = other.actionQuarternary
actionWarning = other.actionWarning
- actionConfirmation = other.actionConfirmation
- actionError = other.actionError
- actionInfo = other.actionInfo
+ actionSuccess = other.actionSuccess
+ actionCritical = other.actionCritical
+ actionInformation = other.actionInformation
formDefault = other.formDefault
formSelected = other.formSelected
formSurface = other.formSurface
@@ -687,8 +688,8 @@ class FirefoxColors(
textPrimary = other.textPrimary
textSecondary = other.textSecondary
textDisabled = other.textDisabled
- textWarning = other.textWarning
- textWarningButton = other.textWarningButton
+ textCritical = other.textCritical
+ textCriticalButton = other.textCriticalButton
textAccent = other.textAccent
textAccentDisabled = other.textAccentDisabled
textOnColorPrimary = other.textOnColorPrimary
@@ -707,8 +708,8 @@ class FirefoxColors(
iconOnColorDisabled = other.iconOnColorDisabled
iconNotice = other.iconNotice
iconButton = other.iconButton
- iconWarning = other.iconWarning
- iconWarningButton = other.iconWarningButton
+ iconCritical = other.iconCritical
+ iconCriticalButton = other.iconCriticalButton
iconAccentViolet = other.iconAccentViolet
iconAccentBlue = other.iconAccentBlue
iconAccentPink = other.iconAccentPink
@@ -725,7 +726,7 @@ class FirefoxColors(
borderFormDefault = other.borderFormDefault
borderAccent = other.borderAccent
borderDisabled = other.borderDisabled
- borderWarning = other.borderWarning
+ borderCritical = other.borderCritical
borderToolbarDivider = other.borderToolbarDivider
}
@@ -747,9 +748,9 @@ class FirefoxColors(
layerGradientStart: Color = this.layerGradientStart,
layerGradientEnd: Color = this.layerGradientEnd,
layerWarning: Color = this.layerWarning,
- layerConfirmation: Color = this.layerConfirmation,
- layerError: Color = this.layerError,
- layerInfo: Color = this.layerInfo,
+ layerSuccess: Color = this.layerSuccess,
+ layerCritical: Color = this.layerCritical,
+ layerInformation: Color = this.layerInformation,
layerSearch: Color = this.layerSearch,
actionPrimary: Color = this.actionPrimary,
actionPrimaryDisabled: Color = this.actionPrimaryDisabled,
@@ -757,9 +758,9 @@ class FirefoxColors(
actionTertiary: Color = this.actionTertiary,
actionQuarternary: Color = this.actionQuarternary,
actionWarning: Color = this.actionWarning,
- actionConfirmation: Color = this.actionConfirmation,
- actionError: Color = this.actionError,
- actionInfo: Color = this.actionInfo,
+ actionSuccess: Color = this.actionSuccess,
+ actionCritical: Color = this.actionCritical,
+ actionInformation: Color = this.actionInformation,
formDefault: Color = this.formDefault,
formSelected: Color = this.formSelected,
formSurface: Color = this.formSurface,
@@ -771,8 +772,8 @@ class FirefoxColors(
textPrimary: Color = this.textPrimary,
textSecondary: Color = this.textSecondary,
textDisabled: Color = this.textDisabled,
- textWarning: Color = this.textWarning,
- textWarningButton: Color = this.textWarningButton,
+ textCritical: Color = this.textCritical,
+ textCriticalButton: Color = this.textCriticalButton,
textAccent: Color = this.textAccent,
textAccentDisabled: Color = this.textAccentDisabled,
textOnColorPrimary: Color = this.textOnColorPrimary,
@@ -791,8 +792,8 @@ class FirefoxColors(
iconOnColorDisabled: Color = this.iconOnColorDisabled,
iconNotice: Color = this.iconNotice,
iconButton: Color = this.iconButton,
- iconWarning: Color = this.iconWarning,
- iconWarningButton: Color = this.iconWarningButton,
+ iconCritical: Color = this.iconCritical,
+ iconCriticalButton: Color = this.iconCriticalButton,
iconAccentViolet: Color = this.iconAccentViolet,
iconAccentBlue: Color = this.iconAccentBlue,
iconAccentPink: Color = this.iconAccentPink,
@@ -809,7 +810,7 @@ class FirefoxColors(
borderFormDefault: Color = this.borderFormDefault,
borderAccent: Color = this.borderAccent,
borderDisabled: Color = this.borderDisabled,
- borderWarning: Color = this.borderWarning,
+ borderWarning: Color = this.borderCritical,
borderToolbarDivider: Color = this.borderToolbarDivider,
): FirefoxColors = FirefoxColors(
layer1 = layer1,
@@ -825,9 +826,9 @@ class FirefoxColors(
layerGradientStart = layerGradientStart,
layerGradientEnd = layerGradientEnd,
layerWarning = layerWarning,
- layerConfirmation = layerConfirmation,
- layerError = layerError,
- layerInfo = layerInfo,
+ layerSuccess = layerSuccess,
+ layerCritical = layerCritical,
+ layerInformation = layerInformation,
layerSearch = layerSearch,
actionPrimary = actionPrimary,
actionPrimaryDisabled = actionPrimaryDisabled,
@@ -835,9 +836,9 @@ class FirefoxColors(
actionTertiary = actionTertiary,
actionQuarternary = actionQuarternary,
actionWarning = actionWarning,
- actionConfirmation = actionConfirmation,
- actionError = actionError,
- actionInfo = actionInfo,
+ actionSuccess = actionSuccess,
+ actionCritical = actionCritical,
+ actionInformation = actionInformation,
formDefault = formDefault,
formSelected = formSelected,
formSurface = formSurface,
@@ -849,8 +850,8 @@ class FirefoxColors(
textPrimary = textPrimary,
textSecondary = textSecondary,
textDisabled = textDisabled,
- textWarning = textWarning,
- textWarningButton = textWarningButton,
+ textCritical = textCritical,
+ textCriticalButton = textCriticalButton,
textAccent = textAccent,
textAccentDisabled = textAccentDisabled,
textOnColorPrimary = textOnColorPrimary,
@@ -869,8 +870,8 @@ class FirefoxColors(
iconOnColorDisabled = iconOnColorDisabled,
iconNotice = iconNotice,
iconButton = iconButton,
- iconWarning = iconWarning,
- iconWarningButton = iconWarningButton,
+ iconCritical = iconCritical,
+ iconCriticalButton = iconCriticalButton,
iconAccentViolet = iconAccentViolet,
iconAccentBlue = iconAccentBlue,
iconAccentPink = iconAccentPink,
@@ -887,7 +888,7 @@ class FirefoxColors(
borderFormDefault = borderFormDefault,
borderAccent = borderAccent,
borderDisabled = borderDisabled,
- borderWarning = borderWarning,
+ borderCritical = borderWarning,
borderToolbarDivider = borderToolbarDivider,
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/DownloadIndicator.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/DownloadIndicator.kt
index 952727fe85..89c9cb47dc 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/DownloadIndicator.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/DownloadIndicator.kt
@@ -14,6 +14,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -26,7 +29,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
-import androidx.compose.ui.semantics.disabled
import androidx.compose.ui.semantics.role
import androidx.compose.ui.unit.dp
import org.mozilla.fenix.R
@@ -87,15 +89,15 @@ fun DownloadIndicator(
modifier = modifier.then(
Modifier
.clearAndSetSemantics {
- disabled()
role = Role.Button
contentDescription?.let { this.contentDescription = contentDescription }
- },
+ }
+ .wrapContentSize(),
),
- enabled = false,
icon = icon,
iconModifier = Modifier
- .rotate(rotationAnimation()),
+ .rotate(rotationAnimation())
+ .size(ButtonDefaults.IconSize),
onClick = {},
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettings.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettings.kt
index d29da59cfd..9edbaef823 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettings.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettings.kt
@@ -46,6 +46,7 @@ fun TranslationSettings(
onNeverTranslationClicked: () -> Unit,
onDownloadLanguageClicked: () -> Unit,
) {
+ val showHeader = showAutomaticTranslations || showNeverTranslate || showDownloads
Column(
modifier = Modifier
.background(
@@ -67,12 +68,12 @@ fun TranslationSettings(
.padding(start = 72.dp, end = 16.dp),
)
- if (item.type.hasDivider) {
+ if (item.type.hasDivider && showHeader) {
Divider(Modifier.padding(top = 8.dp, bottom = 8.dp))
}
}
- if (showAutomaticTranslations || showNeverTranslate || showDownloads) {
+ if (showHeader) {
item {
Text(
text = stringResource(
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettingsFragment.kt
index 5fbd7a2dc1..0859c51bd3 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettingsFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationSettingsFragment.kt
@@ -17,11 +17,9 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
-import androidx.navigation.fragment.navArgs
import mozilla.components.browser.state.action.TranslationsAction
-import mozilla.components.browser.state.selector.findTab
+import mozilla.components.browser.state.state.TranslationsBrowserState
import mozilla.components.browser.state.store.BrowserStore
-import mozilla.components.concept.engine.translate.TranslationPageSettingOperation
import mozilla.components.lib.state.ext.observeAsComposableState
import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.GleanMetrics.Translations
@@ -36,7 +34,6 @@ import org.mozilla.fenix.theme.FirefoxTheme
* A fragment displaying the Firefox Translation settings screen.
*/
class TranslationSettingsFragment : Fragment(), UserInteractionHandler {
- private val args by navArgs()
private val browserStore: BrowserStore by lazy { requireComponents.core.store }
override fun onResume() {
@@ -67,7 +64,7 @@ class TranslationSettingsFragment : Fragment(), UserInteractionHandler {
Translations.action.record(Translations.ActionExtra("global_site_settings"))
findNavController().navigate(
TranslationSettingsFragmentDirections
- .actionTranslationSettingsFragmentToNeverTranslateSitePreferenceFragment(),
+ .actionTranslationSettingsToNeverTranslateSitePreference(),
)
},
onDownloadLanguageClicked = {
@@ -84,19 +81,19 @@ class TranslationSettingsFragment : Fragment(), UserInteractionHandler {
/**
* Set the switch item values.
- * The first one is based on [TranslationPageSettings.alwaysOfferPopup].
+ * The first one is based on [TranslationsBrowserState.offerTranslation].
* The second one is [DownloadLanguageFileDialog] visibility.
* This pop-up will appear if the switch item is unchecked, the phone is in saving mode, and
* doesn't have a WiFi connection.
*/
@Composable
private fun getTranslationSwitchItemList(): MutableList {
- val pageSettingsState = browserStore.observeAsComposableState { state ->
- state.findTab(args.sessionId)?.translationsState?.pageSettings
+ val offerToTranslate = browserStore.observeAsComposableState { state ->
+ state.translationEngine.offerTranslation
}.value
val translationSwitchItems = mutableListOf()
- pageSettingsState?.alwaysOfferPopup?.let {
+ offerToTranslate?.let {
translationSwitchItems.add(
TranslationSwitchItem(
type = TranslationSettingsScreenOption.OfferToTranslate(
@@ -107,10 +104,8 @@ class TranslationSettingsFragment : Fragment(), UserInteractionHandler {
isEnabled = true,
onStateChange = { _, checked ->
browserStore.dispatch(
- TranslationsAction.UpdatePageSettingAction(
- tabId = args.sessionId,
- operation = TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP,
- setting = checked,
+ TranslationsAction.SetGlobalOfferTranslateSettingAction(
+ offerTranslation = checked,
),
)
// Ensures persistence of value
@@ -141,12 +136,15 @@ class TranslationSettingsFragment : Fragment(), UserInteractionHandler {
}
override fun onBackPressed(): Boolean {
- findNavController().navigate(
- TranslationSettingsFragmentDirections.actionTranslationSettingsFragmentToTranslationsDialogFragment(
- sessionId = args.sessionId,
- translationsDialogAccessPoint = TranslationsDialogAccessPoint.TranslationsOptions,
- ),
- )
- return true
+ return if (findNavController().previousBackStackEntry?.destination?.id == R.id.browserFragment) {
+ findNavController().navigate(
+ TranslationSettingsFragmentDirections.actionTranslationSettingsFragmentToTranslationsDialogFragment(
+ translationsDialogAccessPoint = TranslationsDialogAccessPoint.TranslationsOptions,
+ ),
+ )
+ true
+ } else {
+ false
+ }
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt
index 8d4a74e02c..f6e27391be 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt
@@ -171,6 +171,7 @@ internal fun TranslationsOptionsDialog(
context: Context,
showGlobalSettings: Boolean,
translationPageSettings: TranslationPageSettings? = null,
+ offerTranslation: Boolean? = null,
initialFrom: Language? = null,
onStateChange: (TranslationSettingsOption, Boolean) -> Unit,
onBackClicked: () -> Unit,
@@ -181,6 +182,7 @@ internal fun TranslationsOptionsDialog(
showGlobalSettings = showGlobalSettings,
translationOptionsList = getTranslationSwitchItemList(
translationPageSettings = translationPageSettings,
+ offerTranslation = offerTranslation,
initialFrom = initialFrom,
context = context,
onStateChange = onStateChange,
@@ -194,6 +196,7 @@ internal fun TranslationsOptionsDialog(
@Composable
private fun getTranslationSwitchItemList(
translationPageSettings: TranslationPageSettings? = null,
+ offerTranslation: Boolean? = null,
initialFrom: Language? = null,
context: Context,
onStateChange: (TranslationSettingsOption, Boolean) -> Unit,
@@ -201,12 +204,11 @@ private fun getTranslationSwitchItemList(
val translationSwitchItemList = mutableListOf()
translationPageSettings?.let {
- val alwaysOfferPopup = translationPageSettings.alwaysOfferPopup
val alwaysTranslateLanguage = translationPageSettings.alwaysTranslateLanguage
val neverTranslateLanguage = translationPageSettings.neverTranslateLanguage
val neverTranslateSite = translationPageSettings.neverTranslateSite
- alwaysOfferPopup?.let {
+ offerTranslation?.let {
translationSwitchItemList.add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.AlwaysOfferPopup(),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt
index e2d25f82dc..b053e70498 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt
@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.mapNotNull
-import mozilla.components.browser.state.selector.findTab
+import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.state.TranslationsBrowserState
@@ -29,7 +29,6 @@ import java.util.Locale
class TranslationsDialogBinding(
browserStore: BrowserStore,
private val translationsDialogStore: TranslationsDialogStore,
- private val sessionId: String,
private val getTranslatedPageTitle: (localizedFrom: String?, localizedTo: String?) -> String,
) : AbstractBinding(browserStore) {
@@ -42,7 +41,7 @@ class TranslationsDialogBinding(
}
// Session level flows
- val sessionFlow = flow.mapNotNull { state -> state.findTab(sessionId) }
+ val sessionFlow = flow.mapNotNull { state -> state.selectedTab }
.distinctUntilChangedBy {
it.translationsState
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt
index 2c834aea08..727034c0d8 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt
@@ -484,16 +484,18 @@ private fun TranslationErrorWarning(
when (translationError) {
is TranslationError.CouldNotTranslateError -> {
ReviewQualityCheckInfoCard(
- title = stringResource(id = R.string.translation_error_could_not_translate_warning_text),
+ description = stringResource(id = R.string.translation_error_could_not_translate_warning_text),
type = ReviewQualityCheckInfoType.Error,
+ verticalRowAlignment = Alignment.CenterVertically,
modifier = modifier,
)
}
is TranslationError.CouldNotLoadLanguagesError -> {
ReviewQualityCheckInfoCard(
- title = stringResource(id = R.string.translation_error_could_not_load_languages_warning_text),
+ description = stringResource(id = R.string.translation_error_could_not_load_languages_warning_text),
type = ReviewQualityCheckInfoType.Error,
+ verticalRowAlignment = Alignment.CenterVertically,
modifier = modifier,
)
}
@@ -501,7 +503,7 @@ private fun TranslationErrorWarning(
is TranslationError.LanguageNotSupportedError -> {
documentLangDisplayName?.let {
ReviewQualityCheckInfoCard(
- title = stringResource(
+ description = stringResource(
id = R.string.translation_error_language_not_supported_warning_text,
it,
),
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt
index 7e31dd594d..0d5909548e 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt
@@ -20,6 +20,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
@@ -28,7 +29,7 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
-import mozilla.components.browser.state.selector.findTab
+import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.translate.Language
import mozilla.components.concept.engine.translate.TranslationError
@@ -48,6 +49,9 @@ import org.mozilla.fenix.translations.preferences.downloadlanguages.DownloadLang
import org.mozilla.fenix.translations.preferences.downloadlanguages.DownloadLanguageFileDialogType
import org.mozilla.fenix.translations.preferences.downloadlanguages.DownloadLanguagesFeature
+// Friction should be increased, since peek height on this dialog is to fill the screen.
+private const val DIALOG_FRICTION = .65f
+
/**
* The enum is to know what bottom sheet to open.
*/
@@ -78,6 +82,7 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
behavior = BottomSheetBehavior.from(bottomSheet)
behavior?.peekHeight = resources.displayMetrics.heightPixels
behavior?.state = BottomSheetBehavior.STATE_EXPANDED
+ behavior?.hideFriction = DIALOG_FRICTION
}
}
@@ -92,7 +97,6 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
listOf(
TranslationsDialogMiddleware(
browserStore = browserStore,
- sessionId = args.sessionId,
settings = requireContext().settings(),
),
),
@@ -245,7 +249,6 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
feature = TranslationsDialogBinding(
browserStore = browserStore,
translationsDialogStore = translationsDialogStore,
- sessionId = args.sessionId,
getTranslatedPageTitle = { localizedFrom, localizedTo ->
requireContext().getString(
R.string.translations_bottom_sheet_title_translation_completed,
@@ -280,6 +283,8 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
onSettingClicked: () -> Unit,
onShowDownloadLanguageFileDialog: () -> Unit,
) {
+ val localView = LocalView.current
+
TranslationsDialog(
translationsDialogState = translationsDialogState,
learnMoreUrl = learnMoreUrl,
@@ -295,6 +300,11 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
},
onNegativeButtonClicked = {
if (translationsDialogState.isTranslated) {
+ localView.announceForAccessibility(
+ requireContext().getString(
+ R.string.translations_bottom_sheet_restore_accessibility_announcement,
+ ),
+ )
translationsDialogStore.dispatch(TranslationsDialogAction.RestoreTranslation)
}
dismiss()
@@ -384,12 +394,19 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
) {
val pageSettingsState =
browserStore.observeAsComposableState { state ->
- state.findTab(args.sessionId)?.translationsState?.pageSettings
+ state.selectedTab?.translationsState?.pageSettings
}.value
+ val offerTranslation = browserStore.observeAsComposableState { state ->
+ state.translationEngine.offerTranslation
+ }.value
+
+ val localView = LocalView.current
+
TranslationsOptionsDialog(
context = requireContext(),
translationPageSettings = pageSettingsState,
+ offerTranslation = offerTranslation,
showGlobalSettings = showGlobalSettings,
initialFrom = initialFrom,
onStateChange = { type, checked ->
@@ -402,15 +419,17 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
checked,
),
)
+
+ if (checked) {
+ localView.announceForAccessibility(type.descriptionId?.let { getString(it) })
+ }
},
onBackClicked = onBackClicked,
onTranslationSettingsClicked = {
Translations.action.record(Translations.ActionExtra("global_settings"))
findNavController().navigate(
TranslationsDialogFragmentDirections
- .actionTranslationsDialogFragmentToTranslationSettingsFragment(
- sessionId = args.sessionId,
- ),
+ .actionTranslationsDialogFragmentToTranslationSettingsFragment(),
)
},
aboutTranslationClicked = {
@@ -425,7 +444,7 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
setFragmentResult(
TRANSLATION_IN_PROGRESS,
bundleOf(
- SESSION_ID to args.sessionId,
+ SESSION_ID to browserStore.state.selectedTab?.id,
),
)
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt
index 20bfee0d84..cb6ac2c62d 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt
@@ -5,12 +5,12 @@
package org.mozilla.fenix.translations
import mozilla.components.browser.state.action.TranslationsAction
+import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.translate.TranslationOperation
import mozilla.components.concept.engine.translate.TranslationPageSettingOperation
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
-import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.utils.Settings
/**
@@ -18,16 +18,17 @@ import org.mozilla.fenix.utils.Settings
*/
class TranslationsDialogMiddleware(
private val browserStore: BrowserStore,
- private val sessionId: String,
private val settings: Settings,
) : Middleware {
- @Suppress("LongMethod")
+ @Suppress("LongMethod", "CyclomaticComplexMethod")
override fun invoke(
context: MiddlewareContext,
next: (TranslationsDialogAction) -> Unit,
action: TranslationsDialogAction,
) {
+ val sessionId = browserStore.state.selectedTab?.id ?: return
+
when (action) {
is TranslationsDialogAction.InitTranslationsDialog -> {
// If the languages are missing, we should attempt to fetch the supported languages.
@@ -98,10 +99,8 @@ class TranslationsDialogMiddleware(
is TranslationPageSettingsOption.AlwaysOfferPopup -> {
// Ensures the translations engine has the correct value
browserStore.dispatch(
- TranslationsAction.UpdatePageSettingAction(
- tabId = sessionId,
- operation = TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP,
- setting = action.checkValue,
+ TranslationsAction.SetGlobalOfferTranslateSettingAction(
+ offerTranslation = action.checkValue,
),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationItemPreference.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationItemPreference.kt
index 30bfed028e..8c32bc570c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationItemPreference.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationItemPreference.kt
@@ -6,17 +6,20 @@ package org.mozilla.fenix.translations.preferences.automatic
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
+import kotlinx.parcelize.RawValue
+import mozilla.components.concept.engine.translate.Language
+import mozilla.components.concept.engine.translate.LanguageSetting
import org.mozilla.fenix.R
/**
* AutomaticTranslationItem that will appear on Automatic Translation screen.
*
- * @property displayName The text that will appear in the list.
+ * @property language The text that will appear in the list.
* @property automaticTranslationOptionPreference The option that the user selected.
*/
@Parcelize
data class AutomaticTranslationItemPreference(
- val displayName: String,
+ val language: @RawValue Language,
val automaticTranslationOptionPreference: AutomaticTranslationOptionPreference,
) : Parcelable
@@ -65,3 +68,23 @@ sealed class AutomaticTranslationOptionPreference(
),
) : AutomaticTranslationOptionPreference(titleId = titleId, summaryId = summaryId)
}
+
+internal fun getAutomaticTranslationOptionPreference(
+ languageSetting: LanguageSetting,
+): AutomaticTranslationOptionPreference {
+ return when (languageSetting) {
+ LanguageSetting.ALWAYS -> AutomaticTranslationOptionPreference.AlwaysTranslate()
+ LanguageSetting.OFFER -> AutomaticTranslationOptionPreference.OfferToTranslate()
+ LanguageSetting.NEVER -> AutomaticTranslationOptionPreference.NeverTranslate()
+ }
+}
+
+internal fun getLanguageSetting(
+ automaticTranslationItemPreference: AutomaticTranslationOptionPreference,
+): LanguageSetting {
+ return when (automaticTranslationItemPreference) {
+ is AutomaticTranslationOptionPreference.AlwaysTranslate -> LanguageSetting.ALWAYS
+ is AutomaticTranslationOptionPreference.NeverTranslate -> LanguageSetting.NEVER
+ is AutomaticTranslationOptionPreference.OfferToTranslate -> LanguageSetting.OFFER
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreference.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreference.kt
index bbfd3d42ba..a62e6d3a36 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreference.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreference.kt
@@ -21,10 +21,12 @@ import org.mozilla.fenix.theme.FirefoxTheme
* Firefox Automatic Translation Options preference screen.
*
* @param selectedOption Selected option that will come from the translations engine.
+ * @param onItemClick Invoked when the user clicks on a [AutomaticTranslationOptionPreference] from the list.
*/
@Composable
fun AutomaticTranslationOptionsPreference(
selectedOption: AutomaticTranslationOptionPreference,
+ onItemClick: (AutomaticTranslationOptionPreference) -> Unit,
) {
val optionsList = arrayListOf(
AutomaticTranslationOptionPreference.OfferToTranslate(),
@@ -50,6 +52,7 @@ fun AutomaticTranslationOptionsPreference(
maxDescriptionLines = Int.MAX_VALUE,
onClick = {
selected.value = item
+ onItemClick(item)
},
)
}
@@ -63,6 +66,7 @@ private fun AutomaticTranslationOptionsPreview() {
FirefoxTheme {
AutomaticTranslationOptionsPreference(
selectedOption = AutomaticTranslationOptionPreference.AlwaysTranslate(),
+ onItemClick = {},
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreferenceFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreferenceFragment.kt
index b144227312..ad2dea0072 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreferenceFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationOptionsPreferenceFragment.kt
@@ -11,6 +11,9 @@ import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
+import mozilla.components.browser.state.action.TranslationsAction
+import mozilla.components.browser.state.store.BrowserStore
+import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.theme.FirefoxTheme
@@ -19,10 +22,11 @@ import org.mozilla.fenix.theme.FirefoxTheme
*/
class AutomaticTranslationOptionsPreferenceFragment : Fragment() {
private val args by navArgs()
+ private val browserStore: BrowserStore by lazy { requireComponents.core.store }
override fun onResume() {
super.onResume()
- showToolbar(args.selectedTranslationOptionPreference.displayName)
+ args.selectedTranslationOptionPreference.language.localizedDisplayName?.let { showToolbar(it) }
}
override fun onCreateView(
@@ -34,6 +38,14 @@ class AutomaticTranslationOptionsPreferenceFragment : Fragment() {
FirefoxTheme {
AutomaticTranslationOptionsPreference(
selectedOption = args.selectedTranslationOptionPreference.automaticTranslationOptionPreference,
+ onItemClick = {
+ browserStore.dispatch(
+ TranslationsAction.UpdateLanguageSettingsAction(
+ languageCode = args.selectedTranslationOptionPreference.language.code,
+ setting = getLanguageSetting(it),
+ ),
+ )
+ },
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt
index 4ce45c4e2b..76183742c3 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt
@@ -16,6 +16,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
+import mozilla.components.concept.engine.translate.Language
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.list.TextListItem
@@ -58,16 +59,18 @@ fun AutomaticTranslationPreference(
) {
description = stringResource(item.automaticTranslationOptionPreference.titleId)
}
- TextListItem(
- label = item.displayName,
- description = description,
- modifier = Modifier
- .fillMaxWidth()
- .padding(start = 56.dp),
- onClick = {
- onItemClick(item)
- },
- )
+ item.language.localizedDisplayName?.let {
+ TextListItem(
+ label = it,
+ description = description,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 56.dp),
+ onClick = {
+ onItemClick(item)
+ },
+ )
+ }
}
}
}
@@ -78,25 +81,25 @@ internal fun getAutomaticTranslationListPreferences(): List().apply {
add(
AutomaticTranslationItemPreference(
- displayName = Locale.ENGLISH.displayLanguage,
+ language = Language(Locale.ENGLISH.toLanguageTag(), Locale.ENGLISH.displayLanguage),
automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.AlwaysTranslate(),
),
)
add(
AutomaticTranslationItemPreference(
- displayName = Locale.FRENCH.displayLanguage,
+ language = Language(Locale.FRANCE.toLanguageTag(), Locale.FRANCE.displayLanguage),
automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.OfferToTranslate(),
),
)
add(
AutomaticTranslationItemPreference(
- displayName = Locale.GERMAN.displayLanguage,
+ language = Language(Locale.GERMAN.toLanguageTag(), Locale.GERMAN.displayLanguage),
automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.NeverTranslate(),
),
)
add(
AutomaticTranslationItemPreference(
- displayName = Locale.ITALIAN.displayLanguage,
+ language = Language(Locale.ITALIAN.toLanguageTag(), Locale.ITALIAN.displayLanguage),
automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.AlwaysTranslate(),
),
)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreferenceFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreferenceFragment.kt
index 9830a17156..c2b07f98bb 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreferenceFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreferenceFragment.kt
@@ -11,7 +11,13 @@ import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.translate.LanguageSetting
+import mozilla.components.concept.engine.translate.TranslationSupport
+import mozilla.components.concept.engine.translate.findLanguage
+import mozilla.components.lib.state.ext.observeAsComposableState
import org.mozilla.fenix.R
+import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.theme.FirefoxTheme
@@ -19,6 +25,8 @@ import org.mozilla.fenix.theme.FirefoxTheme
* A fragment displaying the Firefox Automatic Translation list screen.
*/
class AutomaticTranslationPreferenceFragment : Fragment() {
+ private val browserStore: BrowserStore by lazy { requireComponents.core.store }
+
override fun onResume() {
super.onResume()
showToolbar(getString(R.string.automatic_translation_toolbar_title_preference))
@@ -31,8 +39,18 @@ class AutomaticTranslationPreferenceFragment : Fragment() {
): View = ComposeView(requireContext()).apply {
setContent {
FirefoxTheme {
+ val languageSettings = browserStore.observeAsComposableState { state ->
+ state.translationEngine.languageSettings
+ }.value
+ val translationSupport = browserStore.observeAsComposableState { state ->
+ state.translationEngine.supportedLanguages
+ }.value
+
AutomaticTranslationPreference(
- automaticTranslationListPreferences = getAutomaticTranslationListPreferences(),
+ automaticTranslationListPreferences = getAutomaticTranslationListPreferences(
+ languageSettings = languageSettings,
+ translationSupport = translationSupport,
+ ),
onItemClick = {
findNavController().navigate(
AutomaticTranslationPreferenceFragmentDirections
@@ -45,4 +63,28 @@ class AutomaticTranslationPreferenceFragment : Fragment() {
}
}
}
+
+ private fun getAutomaticTranslationListPreferences(
+ languageSettings: Map? = null,
+ translationSupport: TranslationSupport? = null,
+ ): List {
+ val automaticTranslationListPreferences =
+ mutableListOf()
+
+ if (translationSupport != null && languageSettings != null) {
+ languageSettings.forEach { entry ->
+ translationSupport.findLanguage(entry.key)?.let {
+ automaticTranslationListPreferences.add(
+ AutomaticTranslationItemPreference(
+ language = it,
+ automaticTranslationOptionPreference = getAutomaticTranslationOptionPreference(
+ entry.value,
+ ),
+ ),
+ )
+ }
+ }
+ }
+ return automaticTranslationListPreferences
+ }
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteDialogPreferenceFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteDialogPreferenceFragment.kt
index 20204b2afb..42caba39a5 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteDialogPreferenceFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteDialogPreferenceFragment.kt
@@ -13,6 +13,9 @@ import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.DialogFragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
+import mozilla.components.browser.state.action.TranslationsAction
+import mozilla.components.browser.state.store.BrowserStore
+import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.theme.FirefoxTheme
/**
@@ -21,6 +24,7 @@ import org.mozilla.fenix.theme.FirefoxTheme
class NeverTranslateSiteDialogPreferenceFragment : DialogFragment() {
private val args by navArgs()
+ private val browserStore: BrowserStore by lazy { requireComponents.core.store }
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
super.onCreateDialog(savedInstanceState).apply {
@@ -37,9 +41,18 @@ class NeverTranslateSiteDialogPreferenceFragment : DialogFragment() {
setContent {
FirefoxTheme {
NeverTranslateSiteDialogPreference(
- websiteUrl = args.websiteUrl,
- onConfirmDelete = { findNavController().popBackStack() },
- onCancel = { findNavController().popBackStack() },
+ websiteUrl = args.neverTranslateSiteUrl,
+ onConfirmDelete = {
+ browserStore.dispatch(
+ TranslationsAction.RemoveNeverTranslateSiteAction(
+ origin = args.neverTranslateSiteUrl,
+ ),
+ )
+ findNavController().popBackStack()
+ },
+ onCancel = {
+ findNavController().popBackStack()
+ },
)
}
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteListItemPreference.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteListItemPreference.kt
deleted file mode 100644
index 6baf2868ef..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSiteListItemPreference.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.translations.preferences.nevertranslatesite
-
-/**
- * NeverTranslateSiteListItemPreference that will appear on [NeverTranslateSitePreferenceFragment] screens.
- *
- * @property websiteUrl The text that will appear on the item list.
- */
-data class NeverTranslateSiteListItemPreference(val websiteUrl: String)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitePreference.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitePreference.kt
deleted file mode 100644
index e8cf6c1a44..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitePreference.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.translations.preferences.nevertranslatesite
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.semantics.Role
-import androidx.compose.ui.semantics.clearAndSetSemantics
-import androidx.compose.ui.semantics.contentDescription
-import androidx.compose.ui.semantics.heading
-import androidx.compose.ui.semantics.role
-import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.unit.dp
-import org.mozilla.fenix.R
-import org.mozilla.fenix.compose.annotation.LightDarkPreview
-import org.mozilla.fenix.compose.list.TextListItem
-import org.mozilla.fenix.theme.FirefoxTheme
-
-/**
- * Never Translate Site preference screen.
- *
- * @param neverTranslateSiteListPreferences List of [NeverTranslateSiteListItemPreference]s to display.
- * @param onItemClick Invoked when the user clicks on the a item from the list.
- */
-@Composable
-fun NeverTranslateSitePreference(
- neverTranslateSiteListPreferences: List,
- onItemClick: (NeverTranslateSiteListItemPreference) -> Unit,
-) {
- Column(
- modifier = Modifier
- .background(
- color = FirefoxTheme.colors.layer1,
- ),
- ) {
- TextListItem(
- label = stringResource(R.string.never_translate_site_header_preference),
- modifier = Modifier
- .padding(
- start = 56.dp,
- )
- .semantics { heading() },
- maxLabelLines = Int.MAX_VALUE,
- )
-
- LazyColumn {
- items(neverTranslateSiteListPreferences) { item: NeverTranslateSiteListItemPreference ->
- val itemContentDescription = stringResource(
- id = R.string.never_translate_site_item_list_content_description_preference,
- item.websiteUrl,
- )
- TextListItem(
- label = item.websiteUrl,
- modifier = Modifier
- .padding(
- start = 56.dp,
- )
- .clearAndSetSemantics {
- role = Role.Button
- contentDescription = itemContentDescription
- },
- onClick = { onItemClick(item) },
- iconPainter = painterResource(R.drawable.mozac_ic_delete_24),
- onIconClick = { onItemClick(item) },
- )
- }
- }
- }
-}
-
-@Composable
-internal fun getNeverTranslateListItemsPreference(): List {
- return mutableListOf().apply {
- add(
- NeverTranslateSiteListItemPreference(
- websiteUrl = "mozilla.org",
- ),
- )
- }
-}
-
-@Composable
-@LightDarkPreview
-private fun NeverTranslateSitePreferencePreview() {
- FirefoxTheme {
- NeverTranslateSitePreference(
- neverTranslateSiteListPreferences = getNeverTranslateListItemsPreference(),
- ) {}
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitePreferenceFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitePreferenceFragment.kt
deleted file mode 100644
index 473d397b86..0000000000
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitePreferenceFragment.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.translations.preferences.nevertranslatesite
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import androidx.navigation.fragment.findNavController
-import org.mozilla.fenix.R
-import org.mozilla.fenix.ext.showToolbar
-import org.mozilla.fenix.theme.FirefoxTheme
-
-/**
- * A fragment displaying never translate site items list.
- */
-class NeverTranslateSitePreferenceFragment : Fragment() {
- override fun onResume() {
- super.onResume()
- showToolbar(getString(R.string.never_translate_site_toolbar_title_preference))
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?,
- ): View = ComposeView(requireContext()).apply {
- setContent {
- FirefoxTheme {
- NeverTranslateSitePreference(
- neverTranslateSiteListPreferences = getNeverTranslateListItemsPreference(),
- onItemClick = {
- findNavController().navigate(
- NeverTranslateSitePreferenceFragmentDirections
- .actionNeverTranslateSitePreferenceFragmentToNeverTranslateSiteDialogPreferenceFragment(
- it.websiteUrl,
- ),
- )
- },
- )
- }
- }
- }
-}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitesPreference.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitesPreference.kt
new file mode 100644
index 0000000000..02215ea1fa
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitesPreference.kt
@@ -0,0 +1,97 @@
+/* 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.translations.preferences.nevertranslatesite
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.heading
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.R
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.compose.list.TextListItem
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * Never Translate Site preference screen.
+ *
+ * @param neverTranslateSitesListPreferences List of site urls to display.
+ * @param onItemClick Invoked when the user clicks on the a item from the list.
+ */
+@Composable
+fun NeverTranslateSitesPreference(
+ neverTranslateSitesListPreferences: List,
+ onItemClick: (String) -> Unit,
+) {
+ Column(
+ modifier = Modifier
+ .background(
+ color = FirefoxTheme.colors.layer1,
+ ),
+ ) {
+ TextListItem(
+ label = stringResource(R.string.never_translate_site_header_preference),
+ modifier = Modifier
+ .padding(
+ start = 56.dp,
+ )
+ .semantics { heading() },
+ maxLabelLines = Int.MAX_VALUE,
+ )
+
+ LazyColumn {
+ items(neverTranslateSitesListPreferences) { item: String ->
+ val itemContentDescription = stringResource(
+ id = R.string.never_translate_site_item_list_content_description_preference,
+ item,
+ )
+ TextListItem(
+ label = item,
+ modifier = Modifier
+ .padding(
+ start = 56.dp,
+ )
+ .clearAndSetSemantics {
+ role = Role.Button
+ contentDescription = itemContentDescription
+ },
+ onClick = { onItemClick(item) },
+ iconPainter = painterResource(R.drawable.mozac_ic_delete_24),
+ onIconClick = { onItemClick(item) },
+ )
+ }
+ }
+ }
+}
+
+@Composable
+internal fun getNeverTranslateSitesList(): List {
+ return mutableListOf().apply {
+ add(
+ "mozilla.org",
+ )
+ }
+}
+
+@Composable
+@LightDarkPreview
+private fun NeverTranslateSitePreferencePreview() {
+ FirefoxTheme {
+ NeverTranslateSitesPreference(
+ neverTranslateSitesListPreferences = getNeverTranslateSitesList(),
+ ) {}
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitesPreferenceFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitesPreferenceFragment.kt
new file mode 100644
index 0000000000..429c89f18f
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/nevertranslatesite/NeverTranslateSitesPreferenceFragment.kt
@@ -0,0 +1,60 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.fenix.translations.preferences.nevertranslatesite
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.ui.platform.ComposeView
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.lib.state.ext.observeAsComposableState
+import org.mozilla.fenix.R
+import org.mozilla.fenix.ext.requireComponents
+import org.mozilla.fenix.ext.showToolbar
+import org.mozilla.fenix.theme.FirefoxTheme
+
+/**
+ * A fragment displaying never translate site items list.
+ */
+class NeverTranslateSitesPreferenceFragment : Fragment() {
+
+ private val browserStore: BrowserStore by lazy { requireComponents.core.store }
+
+ override fun onResume() {
+ super.onResume()
+ showToolbar(getString(R.string.never_translate_site_toolbar_title_preference))
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View = ComposeView(requireContext()).apply {
+ setContent {
+ FirefoxTheme {
+ val neverTranslateSites = browserStore.observeAsComposableState { state ->
+ state.translationEngine.neverTranslateSites
+ }.value
+
+ neverTranslateSites?.let { neverTranslateSitesList ->
+ NeverTranslateSitesPreference(
+ neverTranslateSitesListPreferences = neverTranslateSitesList,
+ onItemClick = {
+ findNavController().navigate(
+ NeverTranslateSitesPreferenceFragmentDirections
+ .actionNeverTranslateSitePreferenceToNeverTranslateSiteDialogPreference(
+ neverTranslateSiteUrl = it,
+ ),
+ )
+ },
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
index ebcf83e21f..5262cad451 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
@@ -35,6 +35,7 @@ import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
+import org.mozilla.fenix.browser.tabstrip.isTabStripEnabled
import org.mozilla.fenix.components.metrics.MozillaProductDetector
import org.mozilla.fenix.components.settings.counterPreference
import org.mozilla.fenix.components.settings.featureFlagPreference
@@ -862,9 +863,6 @@ class Settings(private val appContext: Context) : PreferencesHolder {
return touchExplorationIsEnabled || switchServiceIsEnabled
}
- private val isTablet: Boolean
- get() = appContext.resources.getBoolean(R.bool.tablet)
-
/**
* Indicates if the user has enabled the tab strip feature.
*/
@@ -873,9 +871,6 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = false,
)
- val isTabletAndTabStripEnabled: Boolean
- get() = isTablet && isTabStripEnabled
-
var lastKnownMode: BrowsingMode = BrowsingMode.Normal
get() {
val lastKnownModeWasPrivate = preferences.getBoolean(
@@ -944,7 +939,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
)
val toolbarPosition: ToolbarPosition
- get() = if (isTabletAndTabStripEnabled) {
+ get() = if (appContext.isTabStripEnabled()) {
ToolbarPosition.TOP
} else if (shouldUseBottomToolbar) {
ToolbarPosition.BOTTOM
@@ -1594,9 +1589,9 @@ class Settings(private val appContext: Context) : PreferencesHolder {
/**
* Indicates if the recent saved bookmarks functionality should be visible.
*/
- var showRecentBookmarksFeature by lazyFeatureFlagPreference(
- appContext.getPreferenceKey(R.string.pref_key_recent_bookmarks),
- default = { homescreenSections[HomeScreenSection.RECENTLY_SAVED] == true },
+ var showBookmarksHomeFeature by lazyFeatureFlagPreference(
+ appContext.getPreferenceKey(R.string.pref_key_customization_bookmarks),
+ default = { homescreenSections[HomeScreenSection.BOOKMARKS] == true },
featureFlag = true,
)
@@ -2004,6 +1999,12 @@ class Settings(private val appContext: Context) : PreferencesHolder {
featureFlag = FeatureFlags.completeToolbarRedesignEnabled,
)
+ /**
+ * Indicates if the feature to close synced tabs is enabled.
+ */
+ val enableCloseSyncedTabs: Boolean
+ get() = FxNimbus.features.remoteTabManagement.value().closeTabsEnabled
+
/**
* Returns the height of the bottom toolbar.
*
@@ -2033,7 +2034,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
val isToolbarAtTop = toolbarPosition == ToolbarPosition.TOP
val toolbarHeight = appContext.resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
- return if (isToolbarAtTop && includeTabStrip && isTabletAndTabStripEnabled) {
+ return if (isToolbarAtTop && includeTabStrip) {
toolbarHeight + appContext.resources.getDimensionPixelSize(R.dimen.tab_strip_height)
} else if (isToolbarAtTop) {
toolbarHeight
diff --git a/mobile/android/fenix/app/src/main/res/drawable/microsurvey_success.xml b/mobile/android/fenix/app/src/main/res/drawable/microsurvey_success.xml
new file mode 100644
index 0000000000..2dc8041181
--- /dev/null
+++ b/mobile/android/fenix/app/src/main/res/drawable/microsurvey_success.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/android/fenix/app/src/main/res/layout/fragment_address_editor.xml b/mobile/android/fenix/app/src/main/res/layout/fragment_address_editor.xml
index 4f6e4e14d7..2b02b16a4f 100644
--- a/mobile/android/fenix/app/src/main/res/layout/fragment_address_editor.xml
+++ b/mobile/android/fenix/app/src/main/res/layout/fragment_address_editor.xml
@@ -354,7 +354,7 @@
android:text="@string/addressess_delete_address_button"
android:textAlignment="center"
android:textAllCaps="false"
- android:textColor="@color/fx_mobile_text_color_warning"
+ android:textColor="@color/fx_mobile_text_color_critical"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/email_layout"
app:layout_constraintStart_toStartOf="parent" />
diff --git a/mobile/android/fenix/app/src/main/res/layout/fragment_browser.xml b/mobile/android/fenix/app/src/main/res/layout/fragment_browser.xml
index b61d82c1b9..43794b80d5 100644
--- a/mobile/android/fenix/app/src/main/res/layout/fragment_browser.xml
+++ b/mobile/android/fenix/app/src/main/res/layout/fragment_browser.xml
@@ -45,7 +45,7 @@
android:clickable="true"
android:focusable="true"
android:visibility="gone"
- app:findInPageNoMatchesTextColor="?attr/textWarning"
+ app:findInPageNoMatchesTextColor="?attr/textCritical"
app:findInPageButtonsTint="?attr/textPrimary"
app:findInPageResultCountTextColor="?attr/textPrimary" />
@@ -78,6 +78,8 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:visibility="gone"
+ android:clickable="true"
+ android:focusable="true"
android:elevation="@dimen/browser_fragment_toolbar_elevation"/>
diff --git a/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml b/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml
index f33313ff0d..1e59de2f0b 100644
--- a/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml
+++ b/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml
@@ -118,6 +118,14 @@
+
+
@@ -208,6 +216,13 @@
android:name="scrollToCollection"
android:defaultValue="false"
app:argType="boolean" />
+
+ app:destination="@id/translationsDialogFragment" />
+
+
-
+
+
+
-
+ android:name="org.mozilla.fenix.translations.preferences.nevertranslatesite.NeverTranslateSitesPreferenceFragment">
+
+ android:name="org.mozilla.fenix.components.menu.MenuDialogFragment">
+
+
+
diff --git a/mobile/android/fenix/app/src/main/res/raw/initial_experiments.json b/mobile/android/fenix/app/src/main/res/raw/initial_experiments.json
index f0efae5b6d..d67e48ce88 100644
--- a/mobile/android/fenix/app/src/main/res/raw/initial_experiments.json
+++ b/mobile/android/fenix/app/src/main/res/raw/initial_experiments.json
@@ -68,7 +68,7 @@
"channel": "release",
"userFacingName": "Android Onboarding - Remove Sync Card",
"userFacingDescription": "Mobile Onboarding experiment",
- "isEnrollmentPaused": false,
+ "isEnrollmentPaused": true,
"isRollout": false,
"bucketConfig": {
"randomizationUnit": "nimbus_id",
@@ -160,7 +160,7 @@
],
"targeting": "((is_already_enrolled) || ((isFirstRun == 'true') && (app_version|versionCompare('126.!') >= 0) && (language in ['en'])))",
"startDate": "2024-04-30",
- "enrollmentEndDate": null,
+ "enrollmentEndDate": "2024-05-30",
"endDate": null,
"proposedDuration": 42,
"proposedEnrollment": 14,
@@ -169,111 +169,6 @@
"localizations": null,
"locales": null,
"publishedDate": "2024-04-30T20:18:06.070479Z"
- },
- {
- "schemaVersion": "1.12.0",
- "slug": "splash-screen-max-duration-test-lower-times",
- "id": "splash-screen-max-duration-test-lower-times",
- "arguments": {},
- "application": "org.mozilla.firefox",
- "appName": "fenix",
- "appId": "org.mozilla.firefox",
- "channel": "release",
- "userFacingName": "Splash screen max duration test - lower times",
- "userFacingDescription": "Testing a splashscreen on app launch.",
- "isEnrollmentPaused": true,
- "isRollout": false,
- "bucketConfig": {
- "randomizationUnit": "nimbus_id",
- "namespace": "fenix-splash-screen-release-3",
- "start": 0,
- "count": 10000,
- "total": 10000
- },
- "featureIds": [
- "splash-screen"
- ],
- "probeSets": [],
- "outcomes": [
- {
- "slug": "onboarding",
- "priority": "primary"
- },
- {
- "slug": "default-browser",
- "priority": "primary"
- }
- ],
- "branches": [
- {
- "slug": "control",
- "ratio": 1,
- "feature": {
- "featureId": "this-is-included-for-mobile-pre-96-support",
- "enabled": false,
- "value": {}
- },
- "features": [
- {
- "featureId": "splash-screen",
- "enabled": true,
- "value": {
- "enabled": true,
- "maximum_duration_ms": 0
- }
- }
- ]
- },
- {
- "slug": "treatment-a",
- "ratio": 1,
- "feature": {
- "featureId": "this-is-included-for-mobile-pre-96-support",
- "enabled": false,
- "value": {}
- },
- "features": [
- {
- "featureId": "splash-screen",
- "enabled": true,
- "value": {
- "enabled": true,
- "maximum_duration_ms": 1750
- }
- }
- ]
- },
- {
- "slug": "treatment-b",
- "ratio": 1,
- "feature": {
- "featureId": "this-is-included-for-mobile-pre-96-support",
- "enabled": false,
- "value": {}
- },
- "features": [
- {
- "featureId": "splash-screen",
- "enabled": true,
- "value": {
- "enabled": true,
- "maximum_duration_ms": 2500
- }
- }
- ]
- }
- ],
- "targeting": "((is_already_enrolled) || ((isFirstRun == 'true') && (app_version|versionCompare('124.!') >= 0) && (region in ['AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'])))",
- "startDate": "2024-03-13",
- "enrollmentEndDate": "2024-04-03",
- "endDate": null,
- "proposedDuration": 56,
- "proposedEnrollment": 28,
- "referenceBranch": "control",
- "featureValidationOptOut": false,
- "localizations": null,
- "locales": null,
- "publishedDate": "2024-03-13T15:04:41.938148Z"
}
]
}
diff --git a/mobile/android/fenix/app/src/main/res/values-azb/strings.xml b/mobile/android/fenix/app/src/main/res/values-azb/strings.xml
index 38bae805ff..1be1d508e8 100644
--- a/mobile/android/fenix/app/src/main/res/values-azb/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-azb/strings.xml
@@ -58,13 +58,22 @@
- سون ساخلانانلار
+ سون ساخلانانلار
- بوتون ساخلانمیش بوکمارکلاری گؤستر
+ بوتون ساخلانمیش بوکمارکلاری گؤستر
- قالدیر
+ قالدیر
+
+
+
+ بوکمارکلار
+
+
+ بوتون بوکمارکلاری گؤستر
+
+ قالدیر%1$s موزیلا طرفیندن دوزهدیلمیش.
@@ -210,6 +219,10 @@
تاخیلانلاراوزانتیلار
+
+ اوزانتیْلار مودیریتی
+
+ داها چوْخ اوزانتیْ گؤرحساب بیلگیلری
@@ -230,6 +243,8 @@
معمولی تاغدا آچآناصفحهیه آرتیر
+
+ آنا اکرانا آرتیر…قوْش
@@ -238,12 +253,18 @@
صفحهده تاپ
+
+ یارپاقدا آختار…صفحهنی ترجومه ائله
+ مجموعهده ساخلا…
+
مجموعهده ساخلاپایلاش
+
+ پایلاش…%1$s ایله آچ
@@ -287,10 +308,33 @@
The first parameter is the name of the app defined in app_name (for example: Fenix)-->
%1$s-دا یئنی
+
+ دسکتاپ سایتا گئچ
+
+ آلتلرساخلا
+
+ بو صفحهنی بوکمارک ائله
+
+ بوکمارک دوزهلیشی
+
+ PDF اوْلاراق ساخلا…
+
+ اوْخوجو گؤرونوشونو آچ
+
+ اوْخوجو گؤرونوشونو باغلا
+
+ صفحهنی ترجومه ائله…
+
+
+ %1$s دیلینه چئویر
+
+ پرینت…
+
بوردا هئچ اوزانتی یوخ
@@ -391,8 +435,6 @@
فایرفاکس گیزللیک بیلدیریمی
-
- گیزلیلیک بیلدیریمیزده آرتیق بیلینسیزی قوروماغی سئویریکدیل
+
+ ترجومه
+
+ ترجومهلردیتا سئچیمی
@@ -672,8 +718,11 @@
ایجازه وئریلمهدی
-
- سایتی سیل
+
+
+ لازیم
+
+ گؤیوللوبوتون سایتلار اوچون ایجازه وئر
@@ -696,7 +745,7 @@
قاباقکی تاغلارا قاییت
- سوْن بوکمارکلار
+ سوْن بوکمارکلارسون باخیلانلار
@@ -780,8 +829,6 @@
بوُکمارکلار
-
- گیریشلررمزلر
@@ -810,8 +857,6 @@
The first parameter is the application name, the second is the device manufacturer name
and the third is the device model. -->
%1$s - %2$s %3$s
-
- اعتباری کارتلاراؤدمه آپاریْلاری
diff --git a/mobile/android/fenix/app/src/main/res/values-be/strings.xml b/mobile/android/fenix/app/src/main/res/values-be/strings.xml
index af5728eb07..0c182fa6af 100644
--- a/mobile/android/fenix/app/src/main/res/values-be/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-be/strings.xml
@@ -48,12 +48,20 @@
- Нядаўна захаваныя
+ Нядаўна захаваныя
- Паказаць усе захаваныя закладкі
+ Паказаць усе захаваныя закладкі
- Выдаліць
+ Выдаліць
+
+
+
+ Закладкі
+
+ Паказаць усе закладкі
+
+ Выдаліць%1$s распрацаваны Mozilla.
@@ -141,8 +149,10 @@
Прыватная картка
-
- Хуткі доступ да пароляў
+
+ Паролі
+
+ Хуткі доступ да пароляў
@@ -186,6 +196,10 @@
ДадаткіПашырэнні
+
+ Кіраваць пашырэннямі
+
+ Адкрыйце для сябе іншыя пашырэнніВаш уліковы запіс
@@ -204,20 +218,28 @@
Адкрыць у звычайнай картцыДадаць на хатні экран
+
+ Дадаць на хатні экран…УсталявацьСінхранізаваць ізноўЗнайсці на старонцы
+
+ Знайсці на старонцы…Перакласці старонку
+ Захаваць у калекцыі…
+
Захаваць у калекцыіПадзяліцца
+
+ Падзяліцца…Адкрыць у %1$s
@@ -246,7 +268,50 @@
Уладкаваць хатнюю старонку
- Увайсці
+ Увайсці
+
+
+ Сінхранізуйце паролі, карткі і іншае
+
+ Увайдзіце зноў, каб сінхранізаваць
+
+ Сінхранізацыя прыпынена
+
+ Прыватная картка
+
+ Паролі
+
+ Новае ў %1$s
+
+ Пераключыцца на версію для ПК
+
+ Прылады
+
+ Захаваць
+
+
+ Дадаць закладку на старонку
+
+ Рэдагаваць закладку
+
+ Захаваць як PDF…
+
+ Уключыць рэжым чытання
+
+ Выключыць рэжым чытання
+
+ Перакласці старонку…
+
+ Перакладзена на %1$s
+
+ Друкаваць…
+
+
+
+ Тут няма пашырэнняў
@@ -340,13 +405,13 @@
Паведамленне аб прыватнасці Firefox
-
- Даведайцеся больш у нашым паведамленні аб прыватнасціНам падабаецца забяспечваць вашу бяспекуДаведайцеся, чаму мільёны людзей любяць Firefox
+
+ Бяспечнае агляданне з вялікім выбарамНаш браўзер, падтрыманы некамерцыйнай арганізацыяй, дапамагае не даваць кампаніям таемна сачыць за вамі ў сеціве.
@@ -549,6 +614,10 @@
Падключыцеся, каб аднавіць сінхранізацыюМова
+
+ Пераклад
+
+ ПеракладыВыбар дадзеных
@@ -605,6 +674,8 @@
ПашырэнніУсталяваць дадатак з файла
+
+ Усталяваць пашырэнне з файлаАбвесткі
@@ -613,6 +684,14 @@
Не дазволена
+
+
+ Абавязкова
+
+ Неабавязкова
+
+ Дазволіць для ўсіх сайтаў
+
Уласная калекцыя дадаткаў
@@ -632,7 +711,9 @@
Пераход назад да
- Нядаўнія закладкі
+ Нядаўнія закладкі
+
+ ЗакладкіНядаўна наведаныя
@@ -684,6 +765,8 @@
Даступныя новыя дадаткі
+
+ Даступныя новыя пашырэнніАзнаёмцеся з больш за 100 новых пашырэнняў, якія дазваляюць зрабіць Firefox вашым уласным.
@@ -712,8 +795,6 @@
ГісторыюЗакладкі
-
- ЛагіныПаролі
@@ -740,8 +821,6 @@
and the third is the device model. -->
%1$s на %2$s %3$s
-
- Крэдытныя картыСпосабы аплаты
@@ -1697,13 +1776,9 @@
Вы можаце лёгка дадаць гэты вэб-сайт на хатні экран вашай прылады, каб мець да яго імгненны доступ і аглядаць хутчэй, нібыта гэта асобная праграма.
-
- Лагіны і пароліПаролі
- Захаванне лагінаў і пароляў
-
Захоўваць пароліПытаць пра захаванне
@@ -1718,41 +1793,23 @@
Аўтазапаўненне ў іншых праграмахЗапаўняць імёны карыстальнікаў і паролі ў іншых праграмах на вашай прыладзе.
-
- Дадаць лагінДадаць пароль
-
- Сінхранізацыя лагінаўСінхранізаваць паролі
-
- Сінхранізаваць лагіны паміж прыладаміСінхранізаваць паролі паміж прыладамі
-
- Захаваныя лагіныЗахаваныя паролі
-
- Лагіны, якія вы захаваеце альбо сінхранізуеце праз %s, з’явяцца тут.
-
- Даведацца больш пра сінхранізацыю.Даведайцеся больш пра сінхранізацыюВыключэнні
-
- Не захаваныя лагіны і паролі з’явяцца тут.
-
- Лагіны і паролі не будуць захаваны для гэтых сайтаў.Выдаліць усе выключэнні
-
- Шукаць лагіныПошук пароляў
@@ -1782,18 +1839,12 @@
Паказаць парольСхаваць пароль
-
- Разблакуйце, каб пабачыць захаваныя лагіныРазблакуйце, каб пабачыць захаваныя паролі
-
- Абараніце свае лагіны і пароліАбараніце захаваныя паролі
- Наладзьце графічны ключ, пін ці пароль для блакавання прылады, каб абараніць захаваныя лагіны і паролі ад крадзяжу, калі Вашай прыладай завалодае хтосьці іншы.
-
Наладзьце графічны ключ, пін або пароль для блакавання прылады, каб абараніць захаваныя паролі, калі хтосьці іншы атрымае доступ да вашай прылады.Пазней
@@ -1810,9 +1861,6 @@
Апошняе выкарыстанне
-
- Меню сартавання лагінаў
-
Меню сартавання пароляў
@@ -1821,27 +1869,17 @@
АўтазапаўненнеАдрасы
-
- Крэдытныя картыСпосабы аплаты
- Захоўваць і аўтаматычна запаўняць карты
-
Захоўваць і запаўняць спосабы аплаты
-
- Дадзеныя зашыфраваныСінхранізаваць карты паміж прыладаміСінхранізаваць карты
-
- Дадаць крэдытную картуДадаць карту
-
- Кіраванне захаванымі картаміКіраваць картамі
@@ -1849,13 +1887,9 @@
Дадаць адрасКіраваць адрасамі
-
- Захоўваць і аўтаматычна запаўняць адрасыЗахоўваць і запаўняць адрасы
-
- Уключаць звесткі, такія як нумары, адрасы электроннай пошты і дастаўкіУключае нумары тэлефонаў і адрасы электроннай пошты
@@ -1880,8 +1914,6 @@
Выдаліць карту
- Вы ўпэўнены, што жадаеце выдаліць гэту крэдытную карту?
-
Выдаліць карту?Выдаліць
@@ -1894,23 +1926,14 @@
Захаваныя карты
-
- Калі ласка, увядзіце сапраўдны нумар крэдытнай карты
-
Увядзіце сапраўдны нумар карты
-
- Калі ласка, запоўніце гэтае полеДадайце імяРазблакуйце, каб пабачыць захаваныя карты
- Абараніце свае крэдытныя карты
-
Абараніце захаваныя спосабы аплаты
-
- Наладзьце графічны ключ, пін або пароль для блакавання прылады, каб абараніць захаваныя крэдытныя карты, калі хтось іншы атрымае доступ да вашай прылады.Наладзіць зараз
@@ -1918,8 +1941,6 @@
Разблакуйце сваю прыладу
-
- Разблакуйце, каб выкарыстаць захаваную інфармацыю крэдытнай картыРазблакуйце, каб выкарыстаць захаваныя спосабы аплаты
@@ -1929,12 +1950,6 @@
Змяніць адрасКіраваць адрасамі
-
- Імя
-
- Імя па бацьку
-
- ПрозвішчаНазва
@@ -1960,8 +1975,6 @@
Выдаліць адрас
-
- Вы ўпэўнены, што жадаеце выдаліць гэты адрас?Выдаліць гэты адрас?
@@ -2066,49 +2079,29 @@
ВыдаліцьЗмяніць
-
- Вы сапраўды хочаце выдаліць гэтае лагін?Вы ўпэўнены, што хочаце выдаліць гэты пароль?ВыдаліцьАдмяніць
-
- Налады лагінаПараметры пароля
-
- Тэкставае поле для рэдагавання вэб-адраса для ўваходу ў сістэму.Тэкставае поле для рэдагавання адраса сайта.
-
- Тэкставае поле для рэдагавання імені карыстальніка для ўваходу ў сістэму.Тэкставае поле для рэдагавання імя карыстальніка.
- Тэкставае поле для рэдагавання пароля для ўваходу ў сістэму.
-
Тэкставае поле для рэдагавання пароля.
-
- Захаваць змены ва ўваходных даных.Захаваць змены.
-
- РэдагаваннеЗмяніць пароль
-
- Дадаць новы лагінДадаць пароль
-
- Патрабуецца парольУвядзіце пароль
- Патрабуецца імя карыстальніка
-
Увядзіце імя карыстальнікаПатрабуецца імя хоста
@@ -2474,7 +2467,7 @@
На жаль, мы пакуль не падтрымліваем %1$s.
- Падрабязней
+ Падрабязней
@@ -2490,7 +2483,9 @@
- Параметры перакладу
+ Параметры перакладу
+
+ Параметры перакладуЗаўсёды прапаноўваць пераклад
@@ -2608,12 +2603,14 @@
Інструменты адладкіПерайсці назад
+
+
Інструменты картакКолькасць картак
- Дзейныя
+ ДзейныяНеактыўныя
@@ -2630,4 +2627,35 @@
Дадаць да неактыўных картакДадаць да прыватных картак
-
+
+
+
+
+ Працягнуць
+
+ Паведамленне аб прыватнасці
+
+ Падаць
+
+ Закрыць
+
+ Дзякуй за ваш водгук!
+
+ Вельмі задаволены
+
+ Задаволены
+
+ Нейтральны
+
+ Незадаволены
+
+ Вельмі незадаволены
+
+
+
+ Лагіны
+
+ Бягучы дамен: %s
+
+ Дадаць несапраўдны лагін для гэтага дамена
+
diff --git a/mobile/android/fenix/app/src/main/res/values-bg/strings.xml b/mobile/android/fenix/app/src/main/res/values-bg/strings.xml
index 63fe480125..721c694545 100644
--- a/mobile/android/fenix/app/src/main/res/values-bg/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-bg/strings.xml
@@ -201,6 +201,10 @@
ДобавкиРазширения
+
+ Управление на добавки
+
+ Открийте още разширенияИнформация за профила
@@ -219,6 +223,8 @@
Отваряне в обикновен разделДобавяне към екрана
+
+ Добавяне към началния екран…Инсталиране
@@ -230,9 +236,13 @@
Превеждане на страницатa
+ Запазване в списък…
+
Добавяне към списъкСподеляне
+
+ Споделяне…Отваряне в %1$s
@@ -287,6 +297,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Запазване
+
+ Отбележете тази страница
+
+ Промяна на отметка
+
+ Запазване като PDF…
+
+ Включете изгледа за четене
+
+ Изключете изгледа за четене
+
+ Превеждане на страницата…
+
+ Преведено на %1$s
+
+ Отпечатване…
+
Няма разширения
@@ -383,8 +411,6 @@
бележка за поверителността на Firefox
-
- Научете повече в нашата политика за поверителностОбичаме да ви пазим в безопасностЕзик
- Превод
+ Превод
+
+ ПреводиИзбор на данни
@@ -664,10 +692,6 @@
ЗадължителноПо желание
-
- Четене и промяна на данни на уебсайта
-
- Изтриване на уебсайтРазрешено за всички сайтове
@@ -793,8 +817,6 @@
ИсторияОтметки
-
- РегистрацииПароли
@@ -820,8 +842,6 @@
and the third is the device model. -->
%1$s на %2$s %3$s
-
- Банкови картиНачини на плащане
@@ -837,6 +857,14 @@
Раздел от %s
+
+
+ %1$s затворени раздела: %2$d
+
+ Преглед на наскоро затворените раздели
+
Изключения
@@ -1776,13 +1804,9 @@
Можете лесно да добавите тази страница към началния екран, за да имате бърз достъп до нея, подобно на приложение.
-
- Регистрации и паролиПароли
- Запазване на регистрации и пароли
-
Запазване на паролиПитане за запазване
@@ -1797,47 +1821,29 @@
Попълване в други приложенияПопълват се потребителски имена и пароли в други приложения на устройството.
-
- Добавяне на регистрацияДобавяне на парола
-
- Синхронизиране на регистрацииСинхронизиране на пароли
-
- Синхронизиране на регистрации между устройстваСинхронизиране на пароли между устройства
-
- Запазени регистрацииЗапазени пароли
- Тук се показват нещата, които запазвате или синхронизирате във %s.
-
Паролите, които запазите или синхронизирате с %s ще бъдат изброени тук. Всички запазени пароли са шифровани.
-
- Научете повече за Sync.Научете повече за синхронизиранетоИзключения
-
- Тук се показват регистрации и пароли, които не са запазени.%s няма да запазва пароли за сайтове, изброени тук.
-
- Следните страници няма да запазват регистрации и пароли.%s няма да запази пароли за тези сайтове.Изтриване на всички
-
- Търсене на регистрацияТърсене на пароли
@@ -1867,17 +1873,11 @@
Показване на паролаСкриване на парола
-
- Отключете, за да видите запазените регистрацииОтключете, за да видите запазените пароли
- Защитете вашите данни за вход
-
Защитете запазените пароли
- Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените регистрации и пароли, в случай че някой друг има достъп до него.
-
Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените пароли от достъп, ако някой друг има вашето устройство.По-късно
@@ -1893,8 +1893,6 @@
Име (А-Я)Последно използване
-
- Меню за сортиране на регистрацииМеню за сортиране на пароли
@@ -1904,28 +1902,18 @@
Автоматично попълванеАдреси
-
- Банкови картиНачини на плащане
- Запазване и автоматично попълване на карти
-
Запазване и попълване на начини на плащане
-
- Данните са криптирани%s шифрова всички запазени от вас начини на плащанеСинхронизиране на карти между устройстваСинхронизиране на карти
-
- Добавяне на картаДобавяне на карта
-
- Управление на картиУправление на карти
@@ -1934,12 +1922,8 @@
Управление на адреси
-
- Запазване и попълване на адресиЗапазване и попълване на адреси
-
- Включително номера, електронни адреси и адреси за доставкаВключва телефонни номера и имейл адреси
@@ -1963,8 +1947,6 @@
Изтриване на картата
- Сигурни ли сте, че искате да премахнете тази банкова карта?
-
Изтриване на картата?Премахване
@@ -1976,23 +1958,15 @@
ОтказЗапазени карти
-
- Моля, въведете валиден номер на банкова картаВъведете валиден номер на карта
-
- Попълнете полетоДобавяне на имеОтключете, за да видите запазените карти
- Защитете банковите си карти
-
Защитете запазените начини на плащане
- Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените банкови карти, в случай че някой друг има достъп до него.
-
Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените методи на плащане от достъп, ако някой друг има вашето устройство.Настройване
@@ -2001,9 +1975,6 @@
Отключете устройството си
-
- Отключете, за да използвате запазената банкова карта
-
Отключете, за да използвате запазените методи на плащане
@@ -2012,13 +1983,7 @@
Промяна на адресУправление на адреси
-
- Първо име
-
- Презиме
-
- ФамилияИме
@@ -2045,8 +2010,6 @@
Премахване на адреса
- Сигурни ли сте, че искате да премахнете този адрес?
-
Изтриване на този адрес?Премахване
@@ -2146,49 +2109,29 @@
ИзтриванеРедактиране
-
- Сигурни ли сте, че искате да изтриете тези данни за вход?Сигурни ли сте, че искате да изтриете тази парола?ИзтриванеОтказ
-
- Настройки за входОпции за парола
-
- Текстовото поле за редактиране на адреса на регистрация.Текстовото поле за редактиране на адреса на уебсайта.
-
- Текстовото поле за редактиране на потребителското име на регистрация.Текстовото поле за редактиране на потребителското име.
- Текстовото поле за редактиране на паролата на регистрация.
-
Текстовото поле за редактиране на паролата.
-
- Запазване на промените на регистрацията.Запазване на промените.
-
- РедактиранеРедактиране на паролата
-
- Добавете регистрацияДобавяне на парола
-
- Паролата е задължителнаВъведете парола
- Потребителското име е задължително
-
Въведете потребителско имеИмето на хоста е задължително
@@ -2592,6 +2535,9 @@
Затваряне на листа Преводи
+
+ Някои настройки временно не са налични.
+
Преводи
@@ -2614,6 +2560,9 @@
Изберете език, който да управлявате „винаги превежда“ и „never translate“.
+
+ Езиците не можаха да бъдат заредени. Моля, проверете отново по-късно.
+
Предложение за превод (по подразбиране)
@@ -2636,6 +2585,8 @@
Премахване на %1$s
+
+ Сайтовете не можаха да бъдат заредени. Моля, проверете отново по-късно.Изтриване на %1$s?
@@ -2713,13 +2664,18 @@
Връщане назад
+
+ Отваряне на чекмеджето за отстраняване на грешки
+
Инструменти за разделиБрой на разделите
- Включен
+ Включен
+
+ ВключенИзключени
@@ -2730,6 +2686,16 @@
Инструмент за създаване на разделиКоличество на разделите за създаване
+
+ Текстовото поле е празно
+
+ Моля, въведете само положителни цели числа
+
+ Моля, въведете число, по-голямо от нула
+
+ Надвишен е максималният брой раздели (%1$s), които могат да бъдат генерирани с една операцияДобавяне към активните раздели
@@ -2746,11 +2712,11 @@
Политика на поверителност
- Изпращане
+ Изпращане
- Затваряне
+ Затваряне
- Благодарим ви за отзива!
+ Благодарим ви за отзива!Много доволен
@@ -2762,6 +2728,14 @@
Много недоволен
+
+
+ Отваряне на анкета
+
+ Затваряне на анкетата
+
+ Затваряне
+
Регистрации
diff --git a/mobile/android/fenix/app/src/main/res/values-br/strings.xml b/mobile/android/fenix/app/src/main/res/values-br/strings.xml
index 053dc5cc07..4b32c7a51c 100644
--- a/mobile/android/fenix/app/src/main/res/values-br/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-br/strings.xml
@@ -46,11 +46,19 @@
- Enrollet nevez ’zo
+ Enrollet nevez ’zo
- Diskouez an holl sinedoù enrollet
+ Diskouez an holl sinedoù enrollet
- Dilemel
+ Dilemel
+
+
+
+ Sinedoù
+
+ Diskouez an holl sinedoù
+
+ DilemelGant Mozilla eo produet %1$s.
@@ -100,6 +108,11 @@
Gouzout hiroc’h a-zivout ar gwarez toupinoù hollek
+
+
+ Stokit amañ da gregiñ un estez prevez nevez. Dilemel a raio ho roll istor, ho toupinoù — pep tra.
+
+
Ezhomm a zo haeziñ ar c’hamera. Kit e Arventennoù Android, stokit war an aotreoù ha stokit war aotren.
@@ -185,6 +198,10 @@
AskouezhioùAskouezhioù
+
+ Merañ an askouezhioù
+
+ Dizoloit muioc’h a askouezhioùTitouroù ar gont
@@ -203,18 +220,26 @@
Digeriñ en un ivinell ordinalOuzhpennañ dʼar skramm degemer
+
+ Ouzhpennañ d\'ar skramm degemer…StaliañAdgoubredañKavout er bajennad
+
+ Kavout er bajennad…Treiñ ar bajenn
+ Enrollañ en dastumad…
+
Enrollañ en dastumadRannañ
+
+ Rannañ…Digeriñ e %1$s
@@ -243,11 +268,46 @@
Kennaskañ
+
+ Goubredit gerioù-tremen, ivinelloù ha muioc’h c’hoazh
+
+ Kennaskañ en-dro evit goubredañ
+
+ Ehanet eo ar goubredañIvinell prevez nevezGerioù-tremen
+
+ Nevez e %1$s
+
+ Mont d\'ar stumm evit an urzhiataer
+
+ Ostilhoù
+
+ Enrollañ
+
+ Lakaat ur sined war ar bajenn-mañ
+
+ Kemmañ ar sined
+
+ Enrollañ evel PDF…
+
+ Enaouiñ ar mod lenn
+
+ Kuitaat ar mod lenn
+
+
+ Treiñ ar bajenn…
+
+ Troet e %1$s
+
+ Moullañ…
+
Askouezh ebet da gaout amañ
@@ -262,6 +322,11 @@
Treiñ ar bajenn
+
+ Pajenn troet eus %1$s betek %2$s.
+
Yezh dibabet
@@ -334,8 +399,24 @@
Ket bremañ
+
+
+ Politikerezh prevezded FirefoxHo surentez a zo talvoudus deomp
+
+ Dizoloit perak e plij Firefox da vilionoù a dud
+
+ Merdeiñ diogel ha muioc\'h a zibaboù
+
+ Hor merdeer harpet gant un aozadur hep gounidoù a sikour da herzel an embregerezhioù d\'ho heuliañ pep lec\'h er web.
+
+ Ouzhpenn 100 milion a dud a warez o buhez prevez en ur zibab ur merdeer a zo harpet gant un aozadur hep gounidoù.
+
+ Heulierien anavezet? Stanket diouzhtu. Askouezhioù? Esaeit 700 anezho. PDFoù? Hol lenner enkorfet a lako anezho aes da verañ.
+
+ Hor merdeer harpet gant un aozadur hep gounidoù a sikour da herzel an embregerezhioù d\'ho heuliañ pep lec\'h er web.\n\nGouzout hiroc’h en hor reolennoù a-fet buhez prevez.evezhiadennoù a-fet buhez prevez
@@ -343,6 +424,11 @@
Lakaat da verdeer dre ziouerKet bremañ
+
+ Chomit enrineget pa tremenit eus un trevnad d\'egile
+
+ Pa kennaskit hag e weredekait ar goubredañ eo kreñvoc\'h ho surentez. Fiefox a enrineg ho kerioù-tremen, ho sinedoù hag muioc’h c’hoazh.Kennaskañ
@@ -350,11 +436,23 @@
Gant ar rebuzadurioù e c’hallit chom suroc\'h gant Firefox
+
+ Kas ivinelloù etre ho trevnadoù ha dizoloit keweriusterioù prevezded all Firefox.Gweredekaat ar rebuzadurioùKet bremañ
+
+ Esaeit widjet klask Firefox
+
+ Gant Firefox war ho skramm degemer e c’halloc’h digeriñ ar merdeer a lak ho puhez prevez da gentañ hag a stank an heulierien etre al lec’hiennoù.
+
+ Ouzhpennañ ur widjet FIrefoxKet bremañ
@@ -391,6 +489,8 @@
Luskerioù klaskKinnigoù al luskerioù enklask
+
+ Gwellvezioù ar varrenn chomlec’hBarrenn chomlec\'hioù - Alioù Firefox
@@ -421,6 +521,10 @@
Mod HTTPS-hepken
+
+ Stanker banniel an toupinoù
+
+ Stanker banniel an toupinoù er merdeiñ prevezDiweredekaet evit al lec’hienn-mañ
@@ -437,9 +541,22 @@
Goulenn skor kasetN’eo ket skoret al lec’hienn-mañ c’hoazh
+
+ Gweredekaat stanker banniel an toupinoù evit %1$s?
+
+ Diweredekaat stanker banniel an toupinoù evit %1$s?%1$s n’hall ket nac’hañ ar goulennoù toupinoù war al lec’hienn-mañ. Gallout a rit goulenn e vefe skoret al lec’hienn-mañ en dazont.
+
+ Diweredekaat ha skarzhet e vo an toupinoù hag adkarget al lec’hienn gant %1$s. Digennaskañ a raio ac’hanoc’h ha goullonderiñ a raio ho paner.
+
+ Gweredekaat ha %1$s a glasko nac’hañ bannieloù an toupinoù ent emgefreek war al lec’hienn-mañ.
+
+ %1$s en deus nac’het toupinoù evidoc’h
+
+ Nebeutoc’h a draoù diezhomm, nebeutoc’h a doupinoù ho’ch heuliañ ac’hanoc’h war al lec’hienn-mañ.
+
Klask kennaskañ ent emgefreek gant ar c’homenad HTTPS evit muioc’h a surentez.
@@ -466,6 +583,8 @@
Dafariad kont Mozilla personelaetDafariad Sync personelaet
+
+ Kemmet eo bet an dafariad kontoù Mozilla/Sync. Serriñ a raio an arload evit kemer ar c\'hemmoù e kont…Kont
@@ -486,6 +605,10 @@
Adkennaskit evit kendercʼhel gant ar goubredañYezh
+
+ Troidigezh
+
+ TroidigezhioùDibaboù roadennoù
@@ -512,9 +635,14 @@
Leuniañ an ereoù ent emgefreekKinnigoù paeroniet
+
+ Harpit %1$s gant kuzulioù kevelet diskouezet ur wech an amzerAlioù %1$s
+
+ Kaout alioù eus ar web hervez ho klaskoùDigeriñ ereoù en arloadoù
@@ -534,8 +662,12 @@
Askouezhioù
+
+ AskouezhioùStaliañ un askouezh diouzh ar restr
+
+ Staliañ an askouezh adalek ur restrRebuzadurioù
@@ -549,8 +681,6 @@
RedietDiret
-
- Dilemel al lec’hiennAotren evit an holl lec’hiennoù
@@ -574,7 +704,9 @@
Distreiñ
- Ivinelloù nevez
+ Ivinelloù nevez
+
+ SinedoùGweladennet nevez ’zo
@@ -634,6 +766,8 @@
Diweredekaet eo an askouezhioù evit ar mareKlask adloc’hañ an askouezhioù
+
+ Klaskit adloc’hañ an askouezhioùKenderc’hel gant an askouezhioù bet diweredekaet
@@ -650,8 +784,6 @@
Roll istorSinedoù
-
- Titouroù kennaskañGerioù-tremen
@@ -679,8 +811,6 @@
and the third is the device model. -->
%1$s war %2$s %3$s
-
- Kartennoù kredDoareoù paeañ
@@ -696,6 +826,14 @@
Ivinell eus %s
+
+
+ %1$s ivinell serret: %2$d
+
+ Diskouez an ivinelloù bet serret nevez zo
+
Nemedennoù
@@ -1610,13 +1748,9 @@
Gallout a rit ouzhpennañ al lec’hienn-mañ da bennbajenn ho trevnad evit mont war-eeun ha merdeiñ primoc’h evel ma vefe un arload.
-
- Titouroù kennaskañGerioù-tremen
- Enrollañ an titouroù kennaskañ
-
Enrollañ ar gerioù-tremenGoulenn a-raok enrollañ
@@ -1632,36 +1766,18 @@
Leuniañ anvioù-implijer ha gerioù-tremen en arloadoù-all war ho trevnad.
-
- Ouzhpennañ titouroù kennaskañOuzhpennañ ur ger-tremen
-
- Goubredañ an titouroù kennaskañGoubredañ ar gerioù-tremen
-
- Goubredañ an titouroù kennaskañ dre an trevnadoù
-
- Titouroù kennaskañ enrolletGerioù-tremen enrollet
-
- An titouroù kennaskañ a enrollit pe c’houbredit e %s a vo diskouezet amañ.
-
- Gouzout hiroc’h diwar-benn SyncNemedennoù
-
- An titouroù kennaskañ n’int ket enrollet a vo diskouezet amañ.
-
- Ne vo ket enrollet an titouroù kennaskañ evit al lec’hiennoù-mañ.Dilemel an holl nemedennoù
-
- Klask titouroù kennaskañKlask er gerioù-tremen
@@ -1691,14 +1807,8 @@
Diskouez ar ger-tremenKuzhat ar ger-tremen
-
- Dibrennit evit gwelet ho titouroù kennaskañ enrollet
-
- Diogelit ho titouroù kennaskañDiogelit ho kerioù-tremen enrollet
-
- Arventennit ur patrom morailh, ur PIN pe ur ger-tremen evit gwareziñ ho titouroù kennaskañ enrollet da vezañ lennet gant unan bennak all.Diwezhatoc’h
@@ -1713,34 +1823,22 @@
Anv (A-Z)Arver diwezhañ
-
- Lañser rummañ an titouroù kennaskañLeuniañ ent emgefreekChomlec’hioù
-
- Kartennoù kredDoareoù paeañ
- Enrollañ ha leuniañ ar c’hartennoù en un doare emgefreek
-
Enrollañ ha leuniañ an doareoù paeañ
-
- Rineget eo ar roadennoùGoubredañ ar c’hartennoù kred etre ho trevnadoùGoubredañ ar c\'hartennoù
-
- Ouzhpennañ ur gartenn gredOuzhpennañ ur gartenn
-
- Merañ ar c’hartennoù enrolletMerañ ar c’hartennoù
@@ -1749,12 +1847,8 @@
Merañ ar chomlec’hioù
-
- Enrollañ ha leuniañ ar chomlec’hioù en un doare emgefreekEnrollañ ha leuniañ ar chomlec’hioù
-
- Enkorfañ a ra titouroù evel niverennoù, posteloù ha chomlec’hioùOuzhpennañ ur gartenn
@@ -1776,8 +1870,6 @@
Dilemel ar gartenn
- Ha fellout a ra deocʼh dilemel ar gartenn gred-mañ?
-
Dilemel ar gartenn?Dilemel
@@ -1790,24 +1882,15 @@
Kartennoù enrollet
-
- Biziatait un niverenn kartenn gred talvoudek mar plij.
-
Enankit un niverenn gartenn reizh
-
- Mar plij, leugnit ar maez-mañOuzhpennañ un anvDibrennit da welet ho kartennoù enrollet
-
- Diogelit ho kartennoù kredDiogelit ho toareoù paeañ enrollet
-
- Arventennit ur patrom prennañ, ur PIN pe ur ger-tremen evit gwareziñ ho kartennoù kred enrollet ma vez ho trevnad gant unan bennak all.Arventennañ bremañ
@@ -1815,21 +1898,12 @@
Dibrennit ho trevnad
-
- Dibrennit evit implijout titouroù kartenn gred enrollet
-
Ouzhpennañ ur chomlec’hEmbann ur chomlec’hMerañ ar chomlec’hioù
-
- Añv bihan
-
- Anv kreiz
-
- Anv familhAnv
@@ -1855,8 +1929,6 @@
Dilemel ar chomlec’h
-
- Ha sur oc’h e fell deoc’h dilemel ar chomlec’h-mañ?Dilemel ar chomlec’h-mañ?
@@ -1954,41 +2026,21 @@
DilemelEmbann
-
- Sur oc’h e fell deoc’h dilemel an titour-kennaskañ-mañ?Sur ocʼh e fell deocʼh dilemel ar ger-tremen-mañ?DilemelNullañ
-
- Dibarzhioù an titouroù kennaskañ
-
- Ar vaezienn destenn kemmus evit chomlec’h web an titour kennaskañ.
-
- Ar vaezienn destenn kemmus evit anv arveriad an titour kennaskañ.
-
- Ar vaezienn destenn kemmus evit ger-tremen an titour kennaskañ.
-
- Enrollañ ar c’hemmoù d’an titouroù kennaskañ.Enrollañ ar cʼhemmoù.
-
- EmbannAozañ ar ger-tremen
-
- Ouzhpennañ titouroù kennaskañ nevezOuzhpennañ ur ger-tremen
-
- Ger-tremen azgoulennetEnankit ur ger-tremen
- Anv-implijer rekis
-
Enankit un anv-implijerAnv an ostiz rekis
@@ -2249,6 +2301,9 @@
Ereoù
+
+ Liammoù da gaout
+
@@ -2262,6 +2317,8 @@
Treiñ eDiwezhatoc’h
+
+ Diskouez an destenn orinGraet
@@ -2293,6 +2350,8 @@
Na dreiñ biken %1$sNa dreiñ biken al lec’hienn-mañ
+
+ Arventennoù an droidigezhDiwar-benn an treiñ e-barzh %1$s
@@ -2390,7 +2449,9 @@
Niver a ivinelloù
- Oberiant
+ Oberiant
+
+ OberiantDizoberiant
@@ -2398,4 +2459,16 @@
Hollad
+
+
+
+ Kenderc’hel
+
+
+ Serriñ
+
+ Trugarez da vezañ roet hoc’h ali!
+
+
+ Domani a-vremañ: %s
diff --git a/mobile/android/fenix/app/src/main/res/values-bs/strings.xml b/mobile/android/fenix/app/src/main/res/values-bs/strings.xml
index d32edb20bf..fcd01b9df4 100644
--- a/mobile/android/fenix/app/src/main/res/values-bs/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-bs/strings.xml
@@ -47,11 +47,19 @@
- Nedavno sačuvano
+ Nedavno sačuvano
- Prikaži sve sačuvane oznake
+ Prikaži sve sačuvane oznake
- Ukloni
+ Ukloni
+
+
+
+ Oznake
+
+ Prikaži sve oznake
+
+ Ukloni%1$s je razvila Mozilla.
@@ -185,6 +193,10 @@
Add-oniEkstenzije
+
+ Upravljanje ekstenzijama
+
+ Otkrijte više ekstenzijaPodaci o računu
@@ -203,18 +215,26 @@
Otvori u standardnom tabu Dodaj na Početni ekran
+
+ Dodaj na početni ekran…InstalirajPonovo sinhronizujPronađi na stranici
+
+ Pronađi na stranici…Prevedi stranicu
+ Sačuvaj u kolekciju…
+
Spasi u kolekcijuPodijeli
+
+ Dijeli…Otvori u %1$s
@@ -254,6 +274,34 @@
Lozinke
+
+ Novo u %1$s
+
+ Prebacite se na desktop stranicu
+
+ Alati
+
+ Sačuvaj
+
+ Označi ovu stranicu
+
+ Uredi oznaku
+
+ Sačuvaj kao PDF…
+
+ Uključite Prikaz za čitanje
+
+ Isključite Prikaz za čitanje
+
+ Prevedi stranicu…
+
+ Prevedeno na %1$s
+
+ Štampaj…
+
Ovdje nema ekstenzija
@@ -345,8 +393,6 @@
Firefox obavijest o privatnosti
-
- Saznajte više u našoj obavijesti o privatnostiVolimo da vas čuvamoJezik
+
+ Prijevod
+
+ PrijevodiIzbori podataka
@@ -625,10 +675,6 @@
ObaveznoOpcionalno
-
- Čitajte i mijenjajte podatke web stranice
-
- Izbriši web stranicuDozvoli za sve stranice
@@ -657,7 +703,9 @@
Vrati se nazad
- Nedavne oznake
+ Nedavne oznake
+
+ OznakeNedavno posjećeno
@@ -750,8 +798,6 @@
HistorijuZabilješke
-
- PrijaveLozinke
@@ -778,8 +824,6 @@
and the third is the device model. -->
%1$s na %2$s %3$s
-
- Kreditne karticeNačini plaćanja
@@ -795,6 +839,14 @@
Tab iz %s
+
+
+ %1$s zatvorenih tabova: %2$d
+
+ Pregledajte nedavno zatvorene tabove
+
Izuzeci
@@ -1715,13 +1767,9 @@
Ovu web stranicu možete lahko dodati na Početni ekran uređaja za brz pristup istoj i da surfate brže s iskustvom sličnom aplikaciji.
-
- Prijave i lozinkeLozinke
- Spašene prijave i lozinke
-
Sačuvaj lozinkePitaj za spašavanje
@@ -1736,47 +1784,29 @@
Automatski ispuni u drugim aplikacijamaUnesite korisnička imena i lozinke u druge aplikacije na svom uređaju.
-
- Dodaj prijavuDodaj lozinku
-
- Sinkroniziraj prijaveSinhronizuj lozinke
-
- Sinhronizirajte prijave na svim uređajimaSinhronizuj lozinke na svim uređajima
-
- Spašene prijaveSačuvane lozinke
- Prijave koje spasite ili sinhronizujete sa %s će se prikazati ovdje.
-
Lozinke koje sačuvate ili sinhronizujete sa %s će biti navedene ovdje. Sve lozinke koje sačuvate su šifrovane.
-
- Saznajte više o Syncu.Saznajte više o sinhronizacijiIzuzeci
-
- Prijave i lozinke koje nisu spašene će biti prikazane ovdje.%s neće sačuvati lozinke za web stranice navedene ovdje.
-
- Prijave i lozinke neće biti spašene za ove web stranice.%s neće sačuvati lozinke za ove stranice.Obriši sve izuzetke
-
- Pretraži prijaveTraži lozinke
@@ -1806,17 +1836,11 @@
Prikaži lozinkuSakrij lozinku
-
- Otključajte za pregled spašenih prijavaOtključajte da vidite sačuvane lozinke
- Osigurajte svoje prijave i lozinke
-
Osigurajte svoje sačuvane lozinke
- Podesite pattern za zaključavanje uređaja, PIN ili lozinku da zaštitite vaše spašene prijave i lozinke od pristupa druge osobe koja ima vaš uređaj.
-
Postavite obrazac za zaključavanje uređaja, PIN ili lozinku da zaštitite svoje sačuvane lozinke od pristupa ako neko drugi ima vaš uređaj.Kasnije
@@ -1833,9 +1857,6 @@
Zadnja upotreba
-
- Sortiraj meni prijava
-
Meni za sortiranje lozinki
@@ -1844,16 +1865,10 @@
Automatsko popunjavanjeAdrese
-
- Kreditne karticeNačini plaćanja
- Sačuvajte i automatski popunjavajte kartice
-
Sačuvaj i popuni načine plaćanja
-
- Podaci su šifrovani%s šifruje sve načine plaćanja koje sačuvate
@@ -1861,24 +1876,16 @@
Sinhronizujte kartice na svim uređajimaSinhronizuj kartice
-
- Dodaj kreditnu karticuDodaj karticu
-
- Upravljaj sačuvanim karticamaUpravljajte karticamaDodaj adresuUpravljaj adresama
-
- Sačuvajte i automatski popunjavajte adreseSačuvajte i popunite adrese
-
- Uključite informacije kao što su brojevi, e-mail i adrese za dostavuUključuje brojeve telefona i email adrese
@@ -1902,8 +1909,6 @@
Izbriši karticu
- Jeste li sigurni da želite izbrisati ovu kreditnu karticu?
-
Izbrisati karticu?Izbriši
@@ -1915,23 +1920,15 @@
OtkažiSačuvane kartice
-
- Unesite važeći broj kreditne karticeUnesite važeći broj kartice
-
- Molimo popunite ovo poljeDodaj imeOtključajte da vidite svoje sačuvane kartice
- Osigurajte svoje kreditne kartice
-
Osigurajte svoje sačuvane načine plaćanja
- Postavite obrazac za zaključavanje uređaja, PIN ili lozinku da zaštitite svoje sačuvane kreditne kartice od pristupa ako neko drugi ima vaš uređaj.
-
Postavite obrazac za zaključavanje uređaja, PIN ili lozinku da zaštitite sačuvane načine plaćanja od pristupa ako neko drugi ima vaš uređaj.Podesi odmah
@@ -1939,8 +1936,6 @@
KasnijeOtključajte svoj uređaj
-
- Otključajte za korištenje sačuvanih podataka o kreditnoj karticiOtključajte da koristite sačuvane načine plaćanja
@@ -1950,12 +1945,6 @@
Uredi adresuUpravljaj adresama
-
- Ime
-
- Srednje ime
-
- PrezimeIme
@@ -1981,8 +1970,6 @@
Izbriši adresu
- Jeste li sigurni da želite izbrisati ovu adresu?
-
Izbrisati ovu adresu?Izbriši
@@ -2080,50 +2067,30 @@
ObrišiUredi
-
- Da li ste sigurni da želite obrisati ovu prijavu?Jeste li sigurni da želite izbrisati ovu lozinku?ObrišiOtkaži
-
- Opcije prijaveOpcije lozinke
-
- Izmjenjivo tekstualno polje za web adresu prijave.Tekstualno polje koje se može uređivati za adresu web stranice.
-
- Izmjenjivo tekstualno polje za korisničko ime prijave.Tekstualno polje koje se može uređivati za korisničko ime.
- Izmjenjivo tekstualno polje za lozinku prijave.
-
Tekstualno polje koje se može uređivati za lozinku.
-
- Spasite izmjene za prijavu.Sačuvaj promjene.
-
- UrediUredi lozinku
-
- Dodaj novu prijavuDodaj lozinku
-
- Potrebna lozinkaUnesite lozinku
- Korisničko ime je obavezno
-
Unesite korisničko imeIme hosta je obavezno
@@ -2468,6 +2435,8 @@
Ne sadaPrikaži original
+
+ Originalna neprevedena stranica je učitanaGotovo
@@ -2525,6 +2494,9 @@
Zatvorite list Prijevodi
+
+ Neke postavke su privremeno nedostupne.
+
Prijevodi
@@ -2548,6 +2520,9 @@
Odaberite jezik za upravljanje postavkama ”uvijek prevodi“ i ”nikad ne prevodi“.
+
+ Učitavanje jezika nije uspjelo. Molimo provjerite kasnije.
+
Ponudi prijevod (zadano)
@@ -2570,6 +2545,8 @@
Ukloni %1$s
+
+ Nije moguće učitati web stranice. Molimo provjerite kasnije.Obrisati %1$s?
@@ -2647,13 +2624,18 @@
Idite nazad
+
+ Otvorite ladicu za otklanjanje grešaka
+
Tab alatiBroj tabova
- Aktivno
+ Aktivno
+
+ AktivnoNeaktivno
@@ -2664,6 +2646,16 @@
Alat za kreiranje tabovaKoličina tabova za kreiranje
+
+ Polje za tekst je prazno
+
+ Unesite samo pozitivne cijele brojeve
+
+ Unesite broj veći od nule
+
+ Premašen je maksimalan broj tabova (%1$s) koji se mogu generisati u jednoj operacijiDodaj aktivnim tabovima
@@ -2671,6 +2663,39 @@
Dodaj privatnim tabovima
+
+
+
+ Nastavi
+
+ Popunite ovu anketu
+
+ Napomena o privatnosti
+
+ Pošalji
+
+ Zatvori
+
+ Hvala na povratnim informacijama!
+
+ Vrlo zadovoljan
+
+ Zadovoljan
+
+ Neutralno
+
+ Nezadovoljan
+
+ Vrlo nezadovoljan
+
+
+
+ Otvori anketu
+
+ Zatvori anketu
+
+ Zatvori
+
Prijave
diff --git a/mobile/android/fenix/app/src/main/res/values-cak/strings.xml b/mobile/android/fenix/app/src/main/res/values-cak/strings.xml
index 6fb48978ef..74c64172bf 100644
--- a/mobile/android/fenix/app/src/main/res/values-cak/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-cak/strings.xml
@@ -53,11 +53,19 @@
- K\'a b\'a keyak
+ K\'a b\'a keyak
- Kek\'ut ronojel ri yakon taq yaketal
+ Kek\'ut ronojel ri yakon taq yaketal
- Tiyuj
+ Tiyuj
+
+
+
+ Taq yaketal
+
+ Kek\'ut konojel taq yaketal
+
+ Tiyuj%1$s b\'anon ruma Mozilla.
@@ -146,8 +154,10 @@
K’ak’a’ ichinan ruwi’
-
- Choj okem pa ewan tzij
+
+ Ewan taq tzij
+
+ Choj okem pa ewan tzij
@@ -189,11 +199,13 @@
Tiq\'at
- Taq tz\'aqat
+ Taq tz\'aqat
+
+ Taq k\'amalRutzijol rub\'i\' taqoya\'l
- Majun tz\'aqat wakami
+ Majun tz\'aqat wakamiTo\'ïk
@@ -210,11 +222,13 @@
Titz\'aqatisäx pa ri Rutikirib\'al ruwa
- Tiyak
+ TiyakTixim chikTikanöx pa ruxaq
+
+ Tikanöx pa ruxaq…Titzalq\'omïx ruxaq
@@ -249,6 +263,34 @@
Tawichinaj ri ruxaq atikirib\'al
+
+ Titikirisäx molojri\'ïl
+
+
+ Kexim ewan taq tzij, taq ruwi\', chuqa\' ch\'aqa\' chik
+
+ Titikirisäx chik molojri\'ïl richin ximojri\'ïl
+
+ Q\'aton ximojri\'ïl
+
+ K\'ak\'a\' ichinan ruwi\'
+
+ Ewan taq tzij
+
+ K\'ak\'a\' pa %1$s
+
+ Tik\'ex rik\'in ruxaq kematz\'ib\'
+
+ Samajib\'äl
+
+ Tiyak
+
+
+
+ Majun k\'amal k\'o wawe\'
+
Rutikirib\'al ruwäch
@@ -548,6 +590,8 @@
Tokisäx chik richin nitikirisäx chik ri ximojCh\'ab\'äl
+
+ Tzalq\'omanïkRucha\'ik tzij
@@ -598,10 +642,14 @@
Tajin nel pa ri okisanel richin yejikib\'äx taq jaloj…
- Taq tz’aqat
+ Taq tz’aqat
+
+ Taq k\'amal
- Tiyak ri tz\'aqat rik\'in ri yakb\'äl
+ Tiyak ri tz\'aqat rik\'in ri yakb\'äl
+
+ Tiyak k\'amal rik\'in yakb\'älTaq rutzijol
@@ -610,9 +658,13 @@
Man ya\'on ta q\'ij chi re
+
+
+ Rajowaxik
+
- Kimolik ichinan taq Tz\'aqat
+ Kimolik ichinan taq Tz\'aqatÜTZ
@@ -624,13 +676,13 @@
Rajaw Mol (Winäq ID)
- Xjal kimolaj tz\'aqat. Nitz\'apïx chokoy richin yesamajïx ri taq jaloj…
+ Xjal kimolaj tz\'aqat. Nitz\'apïx chokoy richin yesamajïx ri taq jaloj…Titz\'et chik
- K\'ak\'a\' taq yaketal
+ K\'ak\'a\' taq yaketalK\'a b\'a ketz\'et
@@ -676,20 +728,20 @@
- K\'ak\'a\' taq tz\'aqa ewachel wakami
+ K\'ak\'a\' taq tz\'aqa ewachel wakamiKe\'awila\' +100 k\'ak\'a\' taq k\'amal ri nikiya\' q\'ij chawe\' nawichinaj Firefox.
- Kenik\'öx taq tz\'aqat
+ Kenik\'öx taq tz\'aqat
-
+
- Echupun jumej ri taq tz\'aqat
+ Echupun jumej ri taq tz\'aqat
- Tatojtob\'ej ye\'atzïj chik ri taq tz\'aqat
+ Tatojtob\'ej ye\'atzïj chik ri taq tz\'aqat
- Kesamajïx chik ri chupun taq tz\'aqat
+ Kesamajïx chik ri chupun taq tz\'aqat
@@ -1859,6 +1911,8 @@
Titz\'aqatisäx jun b\'i\'ajMan tiq\'at chik richin ye\'atz\'ët ri tarjeta\' e\'ayakon
+
+ Tab\'ana\' runuk\'ulem jun retal ruq\'atoj okisab\'äl, jun PIN o jun ewan tzij richin nachajij ri kre\'ito\' tarjeta\' e\'ayakon we xa ta k\'o xtichapo ri awokisab\'al.Tib\'an runuk\'ulem wakami
@@ -2201,4 +2255,6 @@ Achi\'el: \nhttps://www.google.com/search?q=%s
+
+
diff --git a/mobile/android/fenix/app/src/main/res/values-co/strings.xml b/mobile/android/fenix/app/src/main/res/values-co/strings.xml
index 01c3c63d1c..29d8291625 100644
--- a/mobile/android/fenix/app/src/main/res/values-co/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-co/strings.xml
@@ -595,7 +595,9 @@
Lingua
- Traduzzione
+ Traduzzione
+
+ TraduzzioniScelta di dati
@@ -2743,7 +2745,7 @@
Numeru d’unghjette
- Attive
+ AttiveInattive
diff --git a/mobile/android/fenix/app/src/main/res/values-cs/strings.xml b/mobile/android/fenix/app/src/main/res/values-cs/strings.xml
index 2f50ff055d..66fc6aa503 100644
--- a/mobile/android/fenix/app/src/main/res/values-cs/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-cs/strings.xml
@@ -204,6 +204,10 @@
DoplňkyRozšíření
+
+ Správa rozšíření
+
+ Objevit další rozšířeníInformace o účtu
@@ -222,6 +226,8 @@
Otevřít v běžném paneluPřidat na plochu
+
+ Přidat na domovskou obrazovku…Nainstalovat
@@ -233,9 +239,13 @@
Přeložit stránku
+ Uložit do sbírky…
+
Uložit do sbírkySdílet
+
+ Sdílet…Otevřít v aplikaci %1$s
@@ -290,6 +300,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Uložit
+
+ Přidat stránku do záložek
+
+ Upravit záložku
+
+ Uložit jako PDF…
+
+ Zapnout zobrazení čtečky
+
+ Vypnout zobrazení čtečky
+
+ Přeložit stránku…
+
+ Přeloženo do jazyka %1$s
+
+ Tisk…
+
Nejsou tu žádná rozšíření
@@ -387,8 +415,6 @@
Zásady ochrany osobních údajů
-
- Další informace naleznete v našich oznámeních o ochraně osobních údajůRádi vás udržujeme v bezpečíJazyk
- Překladač
+ Překladač
+
+ PřekladyMožnosti hlášení
@@ -668,10 +696,6 @@
VyžadovánoVolitelné
-
- Čtení a změna údajů webových stránek
-
- Smazat webovou stránkuPovolit pro všechny stránky
@@ -796,8 +820,6 @@
HistoriiZáložky
-
- Přihlašovací údajeHesla
@@ -825,8 +847,6 @@
and the third is the device model. -->
%1$s na %2$s %3$s
-
- Platební kartyPlatební metody
@@ -842,6 +862,14 @@
Panel z %s
+
+
+ V aplikaci %1$s bylo zavřeno %2$d panelů
+
+ Zobrazení nedávno zavřených panelů
+
Výjimky
@@ -1782,13 +1810,9 @@
Tuto stránku si můžete snadno přidat na domovskou obrazovku svého zařízení. Budete k ní mít okamžitý přístup a prohlížení bude rychlejší se zážitkem jako v aplikaci.
-
- Přihlašovací údajeHesla
- Ukládat přihlašovací údaje
-
Ukládání heselPřed uložením se zeptat
@@ -1803,46 +1827,27 @@
Vyplňování a ukládání uživatelských jmen a hesel v dalších aplikacích na vašem zařízení.
-
- Přidat přihlašovací údaje
-
Přidat heslo
-
- Synchronizovat přihlašovací údajeSynchronizovat hesla
-
- Synchronizovat přihlašovací údaje mezi zařízenímiSynchronizovat hesla napříč zařízeními
-
- Uložené přihlašovací údajeUložená hesla
- Uložené nebo synchronizované údaje aplikace %s se zobrazí tady.
-
Hesla, která uložíte nebo synchronizujete s aplikací %s, budou uvedena zde. Všechna uložená hesla jsou šifrována.
-
- Zjistit více o službě Sync.Další informace o synchronizaciVýjimky
-
- Tady se zobrazí přihlašovací údaje, které se nebudou ukládat.Aplikace %s nebude nikdy ukládat hesla pro stránky uvedené v tomto seznamu.
-
- Pro následující servery se nebudou přihlašovací údaje ukládat.Aplikace %s nebude nikdy ukládat hesla pro tyto stránky.Odebrat všechny výjimky
-
- Hledat přihlašovací údajeHledat v heslech
@@ -1871,17 +1876,11 @@
Zobrazit hesloSkrýt heslo
-
- Odemknout pro zobrazení přihlašovacích údajůPro zobrazení uložených hesel odemkněte
- Zabezpečte své přihlašovací údaje a hesla
-
Zabezpečte svá uložená hesla
- Nastavte si gesto, PIN nebo heslo zámku obrazovky, který ochrání vaše uložené přihlašovací údaje, pokud by se vaše zařízení dostalo do ruky někomu jinému.
-
Nastavte si gesto, PIN nebo heslo zámku obrazovky, který ochrání vaše uložená hesla, pokud by se vaše zařízení dostalo do ruky někomu jinému.Později
@@ -1900,9 +1899,6 @@
Naposledy použito
-
- Seřadit podle
-
Nabídka pro řazení hesel
@@ -1911,41 +1907,27 @@
Automatické vyplňováníAdresy
-
- Platební kartyPlatební metody
- Ukládat a automaticky vyplňovat karty
-
Uložení a vyplnění platebních metod
-
- Data jsou šifrována%s šifruje všechny vaše uložené platební metodySynchronizovat karty napříč zařízenímiSynchronizovat platební karty
-
- Přidat platební kartuPřidat kartu
-
- Správa uložených karetSpravovat kartyPřidat adresuSpráva adres
-
- Ukládat a automaticky vyplňovat adresyUkládat a vyplňovat adresy
-
- Zahrnuje informace jako čísla a e-mailové a doručovací adresyZahrnuje telefonní čísla a e-mailové adresy
@@ -1969,8 +1951,6 @@
Odstranit kartu
- Opravdu chcete tuto platební kartu smazat?
-
Odstranit kartu?Smazat
@@ -1984,24 +1964,15 @@
Uložené karty
-
- Zadejte prosím platné číslo platební karty
-
Zadejte platné číslo karty
-
- Vyplňte prosím toto poleZadejte jménoOdemknout pro zobrazení uložených karet
- Zabezpečte své platební karty
-
Zabezpečte vaše uložené platební metody
- Nastavte si gesto, PIN nebo heslo zámku obrazovky, který ochrání vaše uložené platební karty, pokud by se vaše zařízení dostalo do ruky někomu jinému.
-
Nastavením vzoru zámku zařízení, kódu PIN nebo hesla ochráníte uložené platební metody před přístupem, pokud má vaše zařízení někdo jiný.Nastavit
@@ -2010,9 +1981,6 @@
Odemkněte zařízení
-
- Odemkněte pro použití informací o platební kartě
-
Odemknout pro použití uložených způsobů platby
@@ -2021,12 +1989,6 @@
Upravit adresuSpráva adres
-
- Křestní jméno
-
- Prostřední jméno
-
- PříjmeníNázev
@@ -2053,8 +2015,6 @@
Smazat adresu
- Opravdu chcete tuto adresu smazat?
-
Smazat tuto adresu?Smazat
@@ -2154,49 +2114,29 @@
OdstranitUpravit
-
- Opravdu chcete tyto přihlašovací údaje odstranit?Opravdu chcete smazat toto heslo?OdstranitZrušit
-
- Možnosti přihlášeníMožnosti hesel
-
- Textové pole pro webovou adresu pro přihlašovací údaje.Upravitelné textové pole pro adresu webové stránky.
-
- Textové pole pro uživatelské jméno z přihlašovacích údajů.Upravitelné textové pole pro uživatelské jméno.
- Textové pole pro heslo z přihlašovacích údajů.
-
Upravitelné textové pole pro heslo.
-
- Uložit změny přihlašovacích údajů.Uložit změny.
-
- UpravitUpravit heslo
-
- Přidat nové přihlašovací údajePřidat heslo
-
- Je vyžadováno hesloZadejte heslo
- Uživatelské je povinné
-
Zadejte uživatelské jménoAdresa serveru je povinná
@@ -2603,6 +2543,9 @@
Zavřít Překlady
+
+ Některá nastavení jsou dočasně nedostupná.
+
Překlady
@@ -2626,6 +2569,9 @@
Vyberte jazyk, u kterého chcete spravovat předvolby „vždy překládat“ a „nikdy nepřekládat“.
+
+ Nelze načíst jazyky. Zkuste to prosím později.
+
Nabídnout překlad (výchozí)
@@ -2649,6 +2595,8 @@
Odebrat %1$s
+
+ Nelze načíst stránky. Zkuste to prosím později.Smazat %1$s?
@@ -2727,13 +2675,18 @@
Návrat zpět
+
+ Otevřít ladicí panel
+
Nástroje pro panelyPočet panelů
- Aktivní
+ Aktivní
+
+ AktivníNeaktivní
@@ -2744,6 +2697,16 @@
Nástroj na vytváření panelůPočet panelů, které chcete vytvořit
+
+ Textové pole je prázdné
+
+ Zadejte prosím pouze kladná celá čísla
+
+ Zadejte prosím číslo větší než nula
+
+ Byl překročen maximální počet panelů (%1$s), které mohou být vygenerovány v jedné operaciPřidat mezi aktivní panely
@@ -2760,11 +2723,11 @@
Zásady ochrany osobních údajů
- Odeslat
+ Odeslat
- Zavřít
+ Zavřít
- Děkujeme za vaši zpětnou vazbu!
+ Děkujeme za vaši zpětnou vazbu!Velmi spokojený
@@ -2776,6 +2739,14 @@
Velmi nespokojený
+
+
+ Otevře průzkum
+
+ Zavře průzkum
+
+ Zavřít
+
Přihlašovací údaje
diff --git a/mobile/android/fenix/app/src/main/res/values-cy/strings.xml b/mobile/android/fenix/app/src/main/res/values-cy/strings.xml
index dda3ca243d..0aac4e2556 100644
--- a/mobile/android/fenix/app/src/main/res/values-cy/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-cy/strings.xml
@@ -199,6 +199,10 @@
YchwanegionEstyniadau
+
+ Rheoli estyniadau
+
+ Darganfod rhagor o estyniadauManylion cyfrif
@@ -217,6 +221,8 @@
Agorwch mewn tab arferolYchwanegu i’r sgrin Cartref
+
+ Ychwanegu i\'r sgrin Cartref…Gosod
@@ -228,9 +234,13 @@
Cyfieithu\'r dudalen
+ Cadw i gasgliad…
+
Cadw i GasgliadRhannu
+
+ Rhannu…Agor yn %1$s
@@ -283,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Cadw
+
+ Gosod nod tudalen i\'r dudalen hon
+
+ Golygu nod tudalen
+
+ Cadw fel PDF…
+
+ Trowch y Golwg Darllen ymlaen
+
+ Diffodd y Golwg Darllen
+
+ Cyfieithu tudalen…
+
+ Wedi\'i gyfieithu i %1$s
+
+ Argraffu…
+
Dim estyniadau yma
@@ -378,8 +406,6 @@
Hysbysiad preifatrwydd Firefox
-
- Darllenwch ein hysbysiad preifatrwyddRydyn ni wrth ein bodd yn eich cadw chi’n ddiogelIaith
- Cyfieithu
+ Cyfieithu
+
+ CyfieithuDewisiadau data
@@ -663,10 +691,6 @@
AngenrheidiolDewisol
-
- Darllen a newid data gwefan
-
- Dileu gwefanCaniatáu ar gyfer pob gwefan
@@ -792,8 +816,6 @@
HanesNodau Tudalen
-
- MewngofnodionCyfrineiriau
@@ -820,8 +842,6 @@
and the third is the device model. -->
%1$s o %2$s %3$s
-
- Cardiau credydDulliau talu
@@ -837,6 +857,14 @@
Tab o %s
+
+
+ %1$s tabiau wedi cau: %2$d
+
+ Gweld tabiau a gaewyd yn ddiweddar
+
Eithriadau
@@ -1760,13 +1788,9 @@
Gallwch ychwanegu’r wefan hon yn hawdd i sgrin Cartref eich ffôn i gael mynediad ar unwaith a phori’n gyflymach gyda phrofiad tebyg i ap.
-
- Mewngofnodion a chyfrineiriauCyfrineiriau
- Cadw mewngofnodion a chyfrineiriau
-
Cadw cyfrineiriauGofyn i gadw
@@ -1781,47 +1805,28 @@
Llenwi enwau defnyddwyr a chyfrineiriau mewn apiau eraill ar eich dyfais.
-
- Ychwanegu mewngofnod
-
Ychwanegu cyfrinair
-
- Cydweddu mewngofnodionCydweddu cyfrineiriau
-
- Cydweddu mewngofnodion ar draws dyfeisiauCydweddu cyfrineiriau ar draws dyfeisiau
-
- Mewngofnodion wedi’u cadwCyfrineiriau wedi\'u cadw
- Bydd y mewngofnodi rydych yn eu cadw neu’n cydweddu i %s i’w gweld yma.
-
Bydd y cyfrineiriau rydych yn eu cadw neu eu cydweddu i %s yn cael eu rhestru yma. Mae\'r holl gyfrineiriau rydych chi\'n eu cadw wedi\'u hamgryptio.
-
- Dysgu rhagor am Sync.Dysgwch fwy am gydwedduEithriadau
-
- Bydd mewngofnodion a chyfrineiriau sydd heb eu cadw i’w gweld yma.Fydd %s ddim yn cadw cyfrineiriau ar gyfer gwefannau sy\'n cael eu rhestru yma.
-
- Ni fydd mewngofnodion a chyfrineiriau’n cael eu cadw ar gyfer y gwefannau hyn.Fydd %s ddim yn cadw cyfrineiriau ar gyfer y gwefannau hyn.Dileu pob eithriad
-
- Chwilio mewngofnodionChwilio cyfrineiriau
@@ -1851,17 +1856,11 @@
Dangos cyfrinairCuddio cyfrinair
-
- Datgloi i weld eich mewngofnodi wedi’u cadwDatgloi i weld eich cyfrineiriau wedi\'u cadw
- Diogelu mewngofnodion a chyfrineiriau
-
Diogelwch eich cyfrineiriau wedi\'u cadw
- Creu patrwm cloi dyfais, PIN, neu gyfrinair i ddiogelu eich mewngofnodion a’ch cyfrineiriau sydd wedi’u cadw rhag i rhywun arall sydd â mynediad i’ch dyfais.
-
Gosodwch batrwm clo dyfais, PIN, neu gyfrinair i ddiogelu eich cyfrineiriau sydd wedi\'u cadw rhag i rywun arall sydd â\'ch dyfais gael mynediad iddyn nhw.Yn hwyrach
@@ -1878,8 +1877,6 @@
Enw (A-Z)Defnyddiwyd Diwethaf
-
- Trefnu dewislen mewngofnodiDidoli dewislen cyfrineiriau
@@ -1889,41 +1886,27 @@
AwtolanwCyfeiriadau
-
- Cardiau credydDulliau talu
- Cadw ac awtolanw cardiau
-
Cadw a llanw dulliau talu
-
- Mae data wedi’i amgryptioMae %s yn amgryptio pob dull talu rydych yn ei gadwCydweddu cardiau ar draws dyfeisiauCydweddu cardiau
-
- Ychwanegu cerdyn credydYchwanegu cerdyn
-
- Rheoli cardiau wedi’u cadwRheoli cardiauYchwanegu cyfeiriadRheoli cyfeiriadau
-
- Cadw ac awtolanw cyfeiriadauCadw a llanw cyfeiriadau
-
- Cynhwyswch fanylion fel rhifau, cyfeiriadau e-bost a chludoYn cynnwys rhifau ffôn a chyfeiriadau e-bost
@@ -1947,8 +1930,6 @@
Dileu cerdyn
- Ydych chi’n siŵr eich bod am ddileu’r cerdyn credyd yma?
-
Dileu cerdyn?Dileu
@@ -1962,24 +1943,15 @@
Cardiau wedi’u cadw
-
- Rhowch rif cerdyn credyd dilys
-
Rhoi rif cerdyn dilys
-
- Llanwch y maes yma.Ychwanegu enwDatgloi i weld y cardiau rydych wedi’u cadw
- Diogelwch eich cerdyn credyd
-
Diogelu eich dulliau talu sydd wedi\'u cadw
- Gosodwch batrwm cloi dyfais, PIN, neu gyfrinair i ddiogelu eich mewngofnodion a’ch cyfrineiriau sydd wedi’u cadw rhag i rhywun arall sydd â mynediad i’ch dyfais.
-
Gosodwch batrwm clo dyfais, PIN, neu gyfrinair i ddiogelu eich dulliau talu rhag i rywun arall sydd â\'ch dyfais gael mynediad iddyn nhw.Gosod nawr
@@ -1988,9 +1960,6 @@
Datgloi’ch dyfais
-
- Datglowch i ddefnyddio manylion cerdyn credyd wedi’i storio
-
Datgloi i ddefnyddio dulliau talu wedi\'u cadw
@@ -1999,12 +1968,6 @@
Golygu cyfeiriadRheoli cyfeiriadau
-
- Enw Cyntaf
-
- Enw Canol
-
- Enw OlafEnw
@@ -2030,8 +1993,6 @@
Dileu cyfeiriad
-
- Ydych chi’n siŵr eich bod am ddileu’r cyfeiriad hwn?Dileu\'r cyfeiriad hwn?
@@ -2130,49 +2091,29 @@
DileuGolygu
-
- Ydych chi’n siŵr eich bod eisiau dileu’r mewngofnod?Ydych chi\'n siŵr eich bod am ddileu\'r cyfrinair hwn?DileuDiddymu
-
- Dewisiadau mewngofnodiDewisiadau cyfrineiriau
-
- Maes testun golygadwy cyfeiriad gwe’r mewngofnodi.Maes testun golygadwy y wefan.
-
- Maes testun golygadwy enw defnyddiwr y mewngofnodi.Maes testun golygadwy yr enw defnyddiwr.
- Maes testun golygadwy cyfrinair y mewngofnodi.
-
Maes testun golygadwy y cyfrinair.
-
- Cadw newidiadau i’r mewngofnodi.Cadw newidiadau.
-
- GolyguGolygu cyfrinair
-
- Ychwanegu mewngofnod newyddYchwanegu cyfrinair
-
- Mae angen cyfrinairRhowch gyfrinair
- Mae angen enw defnyddiwr
-
Rhoi enw defnyddiwrMae angen enw gwesteiwr
@@ -2580,6 +2521,9 @@
Cau\'r ddalen Cyfieithiadau
+
+ Nid yw rhai gosodiadau ar gael dros dro.
+
Cyfieithu
@@ -2602,6 +2546,9 @@
Dewiswch iaith i reoli dewisiadau ”cyfieithu bob tro“ a ”peidio â chyfieithu“.
+
+ Methu llwytho ieithoedd. Gwiriwch yn ôl yn nes ymlaen.
+
Cynnig i gyfieithu (rhagosodedig)
@@ -2624,6 +2571,8 @@
Tynnu %1$s
+
+ Methu llwytho gwefannau. Gwiriwch yn ôl yn nes ymlaen.Dileu %1$s?
@@ -2701,13 +2650,18 @@
Symud nôl
+
+ Agor drôr dadfygio
+
Offer TabCyfrif tab
- Gweithredol
+ Gweithredol
+
+ GweithredolAnweithredol
@@ -2718,6 +2672,16 @@
Teclyn creu tabiauNifer y tabiau i\'w creu
+
+ Mae maes testun yn wag
+
+ Rhowch gyfanrifau positif yn unig
+
+ Rhowch rif sy\'n fwy na sero
+
+ Wedi mynd y tu hwnt i uchafswm nifer y tabiau (%1$s) y gellir eu cynhyrchu mewn un gweithrediadYchwanegu at y tabiau gweithredol
@@ -2734,11 +2698,11 @@
Hysbysiad Preifatrwydd
- Cyflwyno
+ Cyflwyno
- Cau
+ Cau
- Diolch am eich adborth!
+ Diolch am eich adborth!Bodlon Iawn
@@ -2750,6 +2714,14 @@
Anfodlon Iawn
+
+
+ Agor arolwg
+
+ Cau\'r arolwg
+
+ Cau
+
Mewngofnodion
diff --git a/mobile/android/fenix/app/src/main/res/values-da/strings.xml b/mobile/android/fenix/app/src/main/res/values-da/strings.xml
index 98609735d8..5759e3a0a6 100644
--- a/mobile/android/fenix/app/src/main/res/values-da/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-da/strings.xml
@@ -49,12 +49,20 @@
- Gemt for nylig
+ Gemt for nylig
- Vis alle gemte bogmærker
+ Vis alle gemte bogmærker
- Fjern
+ Fjern
+
+
+
+ Bogmærker
+
+ Vis alle bogmærker
+
+ Fjern%1$s er lavet af Mozilla.
@@ -192,6 +200,10 @@
TilføjelserUdvidelser
+
+ Håndter udvidelser
+
+ Opdag flere udvidelserKontooplysninger
@@ -210,6 +222,8 @@
Åbn i almindeligt fanebladFøj til startskærm
+
+ Føj til startskærm…Installer
@@ -221,9 +235,13 @@
Oversæt side
+ Gem til samling…
+
Gem til samlingDel
+
+ Del…Åbn i %1$s
@@ -276,6 +294,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Gem
+
+ Bogmærk denne side
+
+ Rediger bogmærke
+
+ Gem som PDF…
+
+ Slå læsevisning til
+
+ Slå læsevisning fra
+
+ Oversæt side…
+
+ Oversat til %1$s
+
+ Udskriv…
+
Ingen udvidelser her
@@ -372,8 +408,6 @@
Privatlivserklæring for Firefox
-
- Læs mere i vores privatlivserklæringVi elsker at holde dig sikkerSprog
- Oversættelse
+ Oversættelse
+
+ OversættelserValg for data
@@ -654,10 +690,6 @@
PåkrævedeValgfrie
-
- Læse og ændre webstedsdata
-
- Slet webstedTillad for alle websteder
@@ -686,7 +718,9 @@
Hop tilbage til
- Seneste bogmærker
+ Seneste bogmærker
+
+ BogmærkerBesøgt for nylig
@@ -780,8 +814,6 @@
HistorikBogmærker
-
- LoginsAdgangskoder
@@ -808,8 +840,6 @@
and the third is the device model. -->
%1$s på %2$s %3$s
-
- BetalingskortBetalingsmetoder
@@ -825,6 +855,14 @@
Faneblad fra %s
+
+
+ %1$s-faneblade lukket: %2$d
+
+ Vis nyligt lukkede faneblade
+
Undtagelser
@@ -1745,13 +1783,9 @@
Du kan nemt føje dette websted til din enheds startskærm for at have hurtig adgang til det og browse hurtigere med en app-lignende oplevelse.
-
- Logins og adgangskoderAdgangskoder
- Gem logins og adgangskoder
-
Gem adgangskoderBed om at gemme
@@ -1766,47 +1800,28 @@
Udfyld brugernavne og adgangskoder i andre apps på din enhed.
-
- Tilføj login
-
Tilføj adgangskode
-
- Synkroniser loginsSynkroniser adgangskoder
-
- Synkroniser logins på tværs af enhederSynkroniser adgangskoder på tværs af enheder
-
- Gemte loginsGemte adgangskoder
- De logins, du gemmer eller synkroniserer til %s, vises her.
-
Adgangskoderne, du gemmer i eller synkroniserer med %s vil blive vist her. Alle dine gemte adgangskoder bliver krypteret.
-
- Læs mere om Sync.Læs mere om synkroniseringUndtagelser
-
- Logins og adgangskoder, der ikke er gemt, vises her.%s gemmer ikke adgangskoder til websteder vist her.
-
- Logins og adgangskoder vil ikke blive gemt for disse websteder.%s gemmer ikke adgangskoder til disse websteder.Slet alle undtagelser
-
- Søg efter loginsSøg efter adgangskoder
@@ -1835,17 +1850,11 @@
Vis adgangskodeSkjul adgangskode
-
- Lås op for at se dine gemte loginsLås op for at se dine gemte adgangskoder
- Gør dine logins og adgangskoder sikre
-
Gør dine gemte adgangskoder sikre
- Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte logins og adgangskoder, hvis de har adgang til din enhed.
-
Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte adgangskoder, hvis de har adgang til din enhed.Senere
@@ -1863,9 +1872,6 @@
Senest brugt
-
- Sortér menuen logins
-
Menuen sorter adgangskoder
@@ -1874,40 +1880,26 @@
AutofyldAdresser
-
- BetalingskortBetalingsmetoder
- Gem og autofyld betalingskort
-
Gem og udfyld betalingsmetoder
-
- Data er krypteret%s krypterer alle betalingsmetoder, du gemmerSynkroniser kort på tværs af enhederSynkroniser kort
-
- Tilføj betalingskortTilføj kort
-
- Håndter gemte kortHåndter kortTilføj adresseHåndter adresser
-
- Gem og autofyld adresserGem og udfyld adresser
-
- Inkluderer oplysninger såsom telefonnumre, mail- og forsendelsesadresserInkluderer telefonnumre og mailadresser
@@ -1931,8 +1923,6 @@
Slet kort
- Er du sikker på, at du vil slette dette betalingskort?
-
Slet kort?Slet
@@ -1946,24 +1936,15 @@
Gemte kort
-
- Indtast et gyldigt betalingskortnummer
-
Indtast et gyldigt kortnummer
-
- Udfyld dette feltTilføj navnLås op for at se dine gemte betalingskort
- Beskyt dine betalingskort
-
Gør dine gemte betalingsmetoder sikre
- Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte betalingskort, hvis de har adgang til din enhed.
-
Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte betalingsmetoder, hvis de har adgang til din enhed.Indstil nu
@@ -1971,8 +1952,6 @@
SenereLås din enhed op
-
- Lås op for at anvende gemte informationer om betalingskortLås op for at bruge gemte betalingsmetoder
@@ -1982,12 +1961,6 @@
Rediger adresseHåndter adresser
-
- Fornavn
-
- Mellemnavn
-
- EfternavnNavn
@@ -2013,8 +1986,6 @@
Slet adresse
- Er du sikker på, at du vil slette denne adresse?
-
Slet denne adresse?Slet
@@ -2113,49 +2084,29 @@
SletRediger
-
- Er du sikker på, at du vil slette dette login?Er du sikker på, at du vil slette denne adgangskode?SletAnnuller
-
- Login-indstillingerAdgangskode-indstillinger
-
- Det redigerbare tekstfelt for login’ets webadresse.Det redigerbare tekstfelt for webadressen.
-
- Det redigerbare tekstfelt for login’ets brugernavn.Det redigerbare tekstfelt for brugernavnet.
- Det redigerbare tekstfelt for login’ets adgangskode.
-
Det redigerbare tekstfelt for adgangskoden.
-
- Gem ændringer til login.Gem ændringer.
-
- RedigerRediger adgangskode
-
- Tilføj nyt loginTilføj adgangskode
-
- Adgangskode påkrævetIndtast en adgangskode
- Brugernavn påkrævet
-
Indtast et brugernavnVærtsnavn påkrævet
@@ -2505,6 +2456,8 @@
Ikke nuVis oprindelig
+
+ Original uoversat side indlæstFærdig
@@ -2562,6 +2515,9 @@
Luk oversættelsesoversigten
+
+ Nogle indstillinger er midlertidigt utilgængelige.
+
Oversættelser
@@ -2584,6 +2540,9 @@
Vælg et sprog for at håndtere indstillingerne ”oversæt altid“ og ”oversæt aldrig“.
+
+ Kunne ikke indlæse sprog. Prøv igen senere.
+
Tilbyd at oversætte (standard)
@@ -2607,6 +2566,8 @@
Fjern %1$s
+
+ Kunne ikke indlæse websteder. Prøv igen senere.Slet %1$s?
@@ -2692,7 +2653,9 @@
Antal faneblade
- Aktive
+ Aktive
+
+ AktiveInaktive
@@ -2703,6 +2666,16 @@
Værktøj til oprettelse af fanebladeAntal faneblade, der skal oprettes
+
+ Tekstfeltet er tomt
+
+ Indtast kun positive heltal
+
+ Indtast et tal større end nul
+
+ Overskredet det maksimale antal faneblade (%1$s), der kan oprettes i én operationFøj til aktive faneblade
@@ -2719,11 +2692,11 @@
Privatlivserklæring
- Indsend
+ Indsend
- Luk
+ Luk
- Tak for tilbagemeldingen!
+ Tak for tilbagemeldingen!Meget tilfreds
@@ -2735,6 +2708,14 @@
Meget utilfreds
+
+
+ Åbn undersøgelse
+
+ Luk undersøgelse
+
+ Luk
+
Logins
diff --git a/mobile/android/fenix/app/src/main/res/values-de/strings.xml b/mobile/android/fenix/app/src/main/res/values-de/strings.xml
index ae6645a6fe..c78b9aa5fa 100644
--- a/mobile/android/fenix/app/src/main/res/values-de/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-de/strings.xml
@@ -202,6 +202,10 @@
Add-onsErweiterungen
+
+ Erweiterungen verwalten
+
+ Weitere Erweiterungen entdeckenKontoinformationen
@@ -220,6 +224,8 @@
In normalem Tab öffnenZum Startbildschirm hinzufügen
+
+ Zum Startbildschirm hinzufügen…Installieren
@@ -231,9 +237,13 @@
Seite übersetzen
+ In Sammlung speichern…
+
In Sammlung speichernTeilen
+
+ Teilen…In %1$s öffnen
@@ -288,6 +298,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Speichern
+
+ Lesezeichen für diese Seite hinzufügen
+
+ Lesezeichen bearbeiten
+
+ Als PDF speichern…
+
+ Leseansicht aktivieren
+
+ Leseansicht deaktivieren
+
+ Seite übersetzen…
+
+ Übersetzt in %1$s
+
+ Drucken…
+
Keine Erweiterungen vorhanden
@@ -385,8 +413,6 @@
Firefox-Datenschutzhinweis
-
- Weitere Informationen finden Sie in unserem DatenschutzhinweisWir schützen Sie gerneSprache
- Übersetzung
+ Übersetzung
+
+ ÜbersetzungenDatenübermittlung
@@ -669,10 +697,6 @@
ErforderlichOptional
-
- Website-Daten lesen und ändern
-
- Website löschenFür alle Websites erlauben
@@ -798,8 +822,6 @@
ChronikLesezeichen
-
- ZugangsdatenPasswörter
@@ -826,8 +848,6 @@
and the third is the device model. -->
%1$s auf %2$s %3$s
-
- KreditkartenZahlungsmethoden
@@ -844,6 +864,14 @@
Tab von %s
+
+
+ %1$s-Tabs geschlossen: %2$d
+
+ Kürzlich geschlossene Tabs anzeigen
+
Ausnahmen
@@ -1796,13 +1824,9 @@
Sie können diese Website einfach zum Startbildschirm Ihres Geräts hinzufügen, um unmittelbaren Zugriff darauf zu haben und sie wie eine App zu nutzen.
-
- Zugangsdaten und PasswörterPasswörter
- Zugangsdaten und Passwörter speichern
-
Passwörter speichernZum Speichern nachfragen
@@ -1818,46 +1842,27 @@
Benutzernamen und Passwörter auf Webseite bei Nutzung von anderen Apps auf Ihrem Gerät automatisch ausfüllen.
-
- Zugangsdaten hinzufügen
-
Passwort hinzufügen
-
- Zugangsdaten synchronisierenPasswörter synchronisieren
-
- Zugangsdaten zwischen Geräten synchronisierenPasswörter geräteübergreifend synchronisieren
-
- Gespeicherte ZugangsdatenGespeicherte Passwörter
- Die Zugangsdaten, die Sie speichern oder mit %s synchronisieren, werden hier angezeigt.
-
Die Passwörter, die Sie speichern oder mit %s synchronisieren, werden hier aufgelistet. Alle gespeicherten Passwörter werden verschlüsselt.
-
- Erfahren Sie mehr über Sync.Weitere Informationen über SyncAusnahmen
-
- Zugangsdaten und Passwörter, die nicht gespeichert werden, werden hier angezeigt.%s speichert keine Passwörter für die hier aufgeführten Websites.
-
- Zugangsdaten und Passwörter werden für diese Websites nicht gespeichert.%s speichert keine Passwörter für diese Websites.Alle Ausnahmen löschen
-
- Zugangsdaten durchsuchenPasswörter durchsuchen
@@ -1886,17 +1891,11 @@
Passwort anzeigenPasswort verbergen
-
- Zum Anzeigen Ihrer gespeicherten Zugangsdaten entsperrenZum Anzeigen Ihrer gespeicherten Passwörter entsperren
- Sichern Sie Ihre Zugangsdaten und Passwörter
-
Sichern Sie Ihre gespeicherten Passwörter
- Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Zugangsdaten und Passwörter zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt.
-
Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Passwörter zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt.Später
@@ -1914,9 +1913,6 @@
Zuletzt verwendet
-
- Menü mit Zugangsdaten sortieren
-
Menü „Passwörter sortieren“
@@ -1925,41 +1921,27 @@
Automatisch ausfüllenAdressen
-
- KreditkartenZahlungsmethoden
- Autovervollständigung für Kreditkartendaten
-
Zahlungsmethoden speichern und ausfüllen
-
- Daten sind verschlüsselt%s verschlüsselt alle von Ihnen gespeicherten ZahlungsmethodenKarten zwischen Geräten synchronisierenKreditkarten synchronisieren
-
- Kreditkarte hinzufügenKarte hinzufügen
-
- Gespeicherte Karten verwaltenKarten verwaltenAdresse hinzufügenAdressen verwalten
-
- Autovervollständigung für AdressenAdressen speichern und ausfüllen
-
- Dies beinhaltetet Nummern, E-Mail- und LieferadressenEnthält Telefonnummern und E-Mail-Adressen
@@ -1983,8 +1965,6 @@
Karte löschen
- Soll diese Kreditkarte wirklich gelöscht werden?
-
Karte löschen?Löschen
@@ -1998,24 +1978,15 @@
Gespeicherte Karten
-
- Bitte geben Sie eine gültige Kreditkartennummer ein
-
Geben Sie eine gültige Kartennummer ein
-
- Bitte füllen Sie dieses Feld ausFügen Sie einen Namen hinzuZum Anzeigen Ihrer gespeicherten Karten entsperren
- Sichern Sie Ihre Kreditkarten
-
Sichern Sie Ihre gespeicherten Zahlungsmethoden
- Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Karten zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt.
-
Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Zahlungsmethoden zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt.Jetzt einrichten
@@ -2024,9 +1995,6 @@
Entsperren Sie Ihr Gerät
-
- Entsperren, um gespeicherte Kreditkartendaten zu verwenden
-
Zum Verwenden Ihrer gespeicherten Zahlungsmethoden entsperren
@@ -2035,12 +2003,6 @@
Adresse bearbeitenAdressen verwalten
-
- Vorname
-
- Zweiter Vorname
-
- NachnameName
@@ -2066,8 +2028,6 @@
Adresse löschen
-
- Soll diese Adresse wirklich gelöscht werden?Diese Adresse löschen?
@@ -2166,49 +2126,29 @@
EntfernenBearbeiten
-
- Sollen diese Zugangsdaten wirklich gelöscht werden?Soll dieses Passwort wirklich gelöscht werden?LöschenAbbrechen
-
- Optionen für ZugangsdatenPasswort-Optionen
-
- Das bearbeitbare Textfeld für die Internetadresse der Zugangsdaten.Das bearbeitbare Textfeld für die Adresse der Website.
-
- Das bearbeitbare Textfeld für den Benutzernamen der Zugangsdaten.Das bearbeitbare Textfeld für den Benutzernamen.
- Das bearbeitbare Textfeld für das Passwort der Zugangsdaten.
-
Das bearbeitbare Textfeld für das Passwort.
-
- Änderungen an Zugangsdaten speichern.Änderungen speichern.
-
- BearbeitenPasswort bearbeiten
-
- Neue Zugangsdaten hinzufügenPasswort hinzufügen
-
- Passwort erforderlichPasswort eingeben
- Benutzername erforderlich
-
Benutzername eingebenHostname erforderlich
@@ -2614,6 +2554,9 @@
Seite „Übersetzungen“ schließen
+
+ Einige Einstellungen sind vorübergehend nicht verfügbar.
+
Übersetzungen
@@ -2636,6 +2579,9 @@
Wählen Sie eine Sprache aus, um die Einstellungen für „Immer übersetzen“ und „Nie übersetzen“ zu verwalten.
+
+ Sprachen konnten nicht geladen werden. Bitte versuchen Sie es später erneut.
+
Übersetzung anbieten (Standard)
@@ -2658,6 +2604,8 @@
%1$s entfernen
+
+ Websites konnten nicht geladen werden. Bitte versuchen Sie es später erneut.%1$s löschen?
@@ -2735,13 +2683,18 @@
Rückwärts navigieren
+
+ Debug-Schublade öffnen
+
Tab-WerkzeugeTab-Anzahl
- Aktiv
+ Aktiv
+
+ AktivInaktiv
@@ -2752,6 +2705,16 @@
Werkzeug zur Tab-ErstellungZu erstellende Tab-Anzahl
+
+ Textfeld ist leer
+
+ Bitte geben Sie nur positive ganze Zahlen ein
+
+ Bitte geben Sie eine Zahl größer als 0 ein
+
+ Die maximale Anzahl an Tabs (%1$s) wurde überschritten, die in einem Arbeitsschritt erzeugt werden kannZu aktiven Tabs hinzufügen
@@ -2768,11 +2731,11 @@
Datenschutzhinweis
- Absenden
+ Absenden
- Schließen
+ Schließen
- Danke für Ihr Feedback!
+ Danke für Ihr Feedback!Sehr zufrieden
@@ -2784,6 +2747,14 @@
Sehr unzufrieden
+
+
+ Umfrage öffnen
+
+ Umfrage schließen
+
+ Schließen
+
Zugangsdaten
diff --git a/mobile/android/fenix/app/src/main/res/values-dsb/strings.xml b/mobile/android/fenix/app/src/main/res/values-dsb/strings.xml
index 45de14681f..de2fba4cb7 100644
--- a/mobile/android/fenix/app/src/main/res/values-dsb/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-dsb/strings.xml
@@ -200,6 +200,10 @@
DodankiRozšyrjenja
+
+ Rozšyrjenja zastojaś
+
+ Dalšne rozšyrjenja namakaśKontowe informacije
@@ -218,6 +222,8 @@
W normalnem rejtariku wócyniśStartowej wobrazowce pśidaś
+
+ Startowej wobrazowce pśidaś…Instalěrowaś
@@ -229,9 +235,13 @@
Bok pśełožyś
+ Do zběrki składowaś…
+
Do zběrki składowaśŹěliś
+
+ Źěliś…W %1$s wócyniś
@@ -284,6 +294,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Składowaś
+
+ Toś ten bok ako cytańske znamje składowaś
+
+ Cytańske znamje wobźěłaś
+
+ Ako PDF składowaś…
+
+ Cytański naglěd zmóžniś
+
+ Cytański naglěd znjemóžniś
+
+ Bok pśełožyś…
+
+ Pśełožony do rěcy %1$s
+
+ Śišćaś…
+
Žedne rozšyrjenja how
@@ -379,8 +407,6 @@
Powěźeńka priwatnosći Firefox
-
- Zgóńśo wěcej w našej powěźeńce priwatnosćiŠćitamy was radRěc
- Pśełožk
+ Pśełožk
+
+ PśełožkiDatowy wuběrki
@@ -661,10 +689,6 @@
TrjebnyNa žycenje
-
- Websedłowe daty cytaś a změniś
-
- Websedło wulašowaśZa wšykne sedła dowóliś
@@ -790,8 +814,6 @@
HistorijaCytańske znamjenja
-
- PśizjawjenjaGronidła
@@ -818,8 +840,6 @@
and the third is the device model. -->
%1$s wót %2$s %3$s
-
- Kreditowe kórtyPłaśeńske metody
@@ -835,6 +855,14 @@
Rajtark z %s
+
+
+ Rejtariki %1$s zacynjone: %2$d
+
+ Rowno zacynjone rejtariki pokazaś
+
Wuwześa
@@ -1762,13 +1790,9 @@
Móžośo startowej wobrazowce swójogo rěda toś to websedło lažko pśidaś, aby direktny pśistup měł a malsnjej z dožywjenim nałoženja pśeglědował.
-
- Pśizjawjenja a gronidłaGronidła
- Pśizjawjenja a gronidła składowaś
-
Gronidła składowaśPśed składowanim se pšašaś
@@ -1783,46 +1807,27 @@
Wužywaŕske mjenja a gronidła w drugich nałoženjach na wašom rěźe zasajźiś.
-
- Pśizjawjenje pśidaś
-
Gronidło pśidaś
-
- Pśizjawjenja synchronizěrowaśGronidła synchronizěrowaś
-
- Pśizjawjenja mjazy rědami synchronizěrowaśGronidła pśez rědy synchronizěrowaś
-
- Skłaźone pśizjawjenjaSkłaźone gronidła
- Pśizjawjenja, kótarež składujośo abo z %s synchronizěrujośo, se how pokažu.
-
Gronidła, kótarež składujośo abo z %s synchronizěrujośo, se how nalicyju. Wšykne gronidła, kótarež składujośo, se koděruju.
-
- Zgóńśo wěcej wó Sync.Zgóńśo wěcej wó syncWuwześa
-
- Pśizjawjenja a gronidła, kótarež se njeskładuju, se how pokažu.%s gronidła za sedła njeskładujo, kótarež su how nalicone.
-
- Pśizjawjenja a gronidła se za toś te sedła njeskładuju.%s gronidła za toś te sedła njeskładujo.Wšykne wuwześa wulašowaś
-
- Pśizjawjenja pytaśGronidła pśepytaś
@@ -1852,17 +1857,11 @@
Gronidło pokazaśGronidła schowaś
-
- Za zwobraznjowanje wašych skłaźonych pśizjawjenjow wótwóriśZa zwobraznjowanje wašych skłaźonych kreditowych gronidłow wótwóriś
- Zawěsććo swóje pśizjawjenja a gronidła
-
Zawěsććo swóje skłaźone gronidła
- Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym pśizjawjenjam a gronidłam zajźował, jolic něchten drugi ma waš rěd.
-
Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym gronidłam zajźował, jolic něchten drugi ma waš rěd.Pózdźej
@@ -1880,8 +1879,6 @@
Mjenju (A-Z)Slědnem wužyśu
-
- Meni pśizjawjeńskich datow sortěrowaśMeni „Gronidła sortěrowaś“
@@ -1891,41 +1888,27 @@
Awtomatiski wupołniśAdrese
-
- Kreditowe kórtyPłaśeńske metody
- Kórty składowaś a awtomatiski wupołniś
-
Płaśeńske metody składowaś a wupołniś
-
- Daty su skoděrowane%s wšykne płaśeńske metody koděrujo, kótarež składujośoKórty pśez rědy synchronizěrowaśKórty synchronizěrowaś
-
- Kreditowu kórtu pśidaśKórtu pśidaś
-
- Skłaźone kórty zastojaśKórty zastojaśAdresu pśidaśAdrese zastojaś
-
- Adrese składowaś a awtomatiski wupołniśAdrese składowaś a wupołniś
-
- Informacije ako licby, e-mailowe a rozpósłańske adrese zapśimjeśWopśimujo telefonowe numery a e-mailowe adrese
@@ -1949,8 +1932,6 @@
Kórtu wulašowaś
- Cośo napšawdu toś tu kreditowu kórtu lašowaś?
-
Kórtu wulašowaś?Lašowaś
@@ -1964,24 +1945,15 @@
Skłaźone kórty
-
- Pšosym zapódajśo płaśiwy numer kreditoweje kórty
-
Zapódajśo płaśiwy kórtowy numer
-
- Pšosym wupołńśo toś to póloPśidajśo měZa zwobraznjowanje wašych skłaźonych kreditowych kórtow wótwóriś
- Kreditowe kórty zawěsćiś
-
Zawěsććo swóje skłaźone płaśeńske metody
- Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym kreditowym kórtam zajźował, jolic něchten drugi ma waš rěd.
-
Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym płaśeńskim metodam zajźował, jolic něchten drugi ma waš rěd.Něnto konfigurěrowaś
@@ -1990,9 +1962,6 @@
Wótwóŕśo swój rěd
-
- Blokěrowanje wótpóraś, aby se skłaźone informacije kreditoweje kórty wužywali
-
Wótwóriś, aby wy skłaźone płaśeńske metody wužywał
@@ -2001,12 +1970,6 @@
Adresu wobźěłaśAdrese zastojaś
-
- Pśedmě
-
- Druge pśedmě
-
- Familijowe měMě
@@ -2032,8 +1995,6 @@
Adresu lašowaś
-
- Cośo napšawdu toś tu adresu wulašowaś?Toś tu adresu lašowaś?
@@ -2132,49 +2093,29 @@
LašowaśWobźěłaś
-
- Cośo napšawdu toś to pśizjawjenje lašowaś?Cośo napšawdu toś to gronidło lašowaś?LašowaśPśetergnuś
-
- Pśizjawjeńske nastajenjaGronidłowe nastajenja
-
- Wobźěłujobne tekstowe pólo za webadresu pśizjawjenja.Wobźěłujobne tekstowe pólo za adresu websedła.
-
- Wobźěłujobne tekstowe pólo za wužywaŕske mě pśizjawjenja.Wobźěłujobne tekstowe pólo za wužywaŕske mě.
- Wobźěłujobne tekstowe pólo za gronidło pśizjawjenja.
-
Wobźěłujobne tekstowe pólo za gronidło.
-
- Změny pśizjawjenja składowaśZměny składowaś.
-
- WobźěłaśGronidło wobźěłaś
-
- Nowe pśizjawjenje pśidaśGronidło pśidaś
-
- Gronidło trěbneGronidło zapódaś
- Wužywaŕske mě trěbne.
-
Wužywaŕske mě zapódaśHostmě trěbne.
@@ -2583,6 +2524,9 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
Bok Pśełožki zacyniś
+
+ Někotare nastajenja njejsu nachylu k dispoziciji.
+
Pśełožki
@@ -2605,6 +2549,9 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
Wubjeŕśo rěc, aby nastajeni „pśecej pśełožyś“ a „nigda njepśełožyś“ zastojał.
+
+ Rěcy njejsu se dali zacytaś. Pšosym wopytajśo pózdźej hyšći raz.
+
Pśełožk póbitowaś (standard)
@@ -2628,6 +2575,8 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
%1$s wótwónoźeś
+
+ Sedła njejsu se dali zacytaś. Pšosym wopytajśo pózdźej hyšći raz.%1$s lašowaś?
@@ -2705,13 +2654,18 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
Slědk nawigěrowaś
+
+ Debug drawer wócyniś
+
Rejtarikowe rědyLicba rejtarikow
- Aktiwny
+ Aktiwny
+
+ AktiwnyNjeaktiwny
@@ -2722,6 +2676,16 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
Rěd za napóranje rejtarikowLicba rejtarikow, kótarež se maju napóraś
+
+ Tekstowe pólo jo prozne
+
+ Pšosym zapódajśo jano pozitiwne cełe licby
+
+ Pšosym zapódajśo licbu, kótaraž jo wětša ako nula
+
+ Maksimalna licba rejtarikow (%1$s), kótarež daju se w jadnej operaciji generěrowaś, jo pśekšoconaAktiwnym rejtarikam pśidaś
@@ -2738,11 +2702,11 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
Powěźeńka priwatnosći
- Wótpósłaś
+ Wótpósłaś
- Zacyniś
+ Zacyniś
- Źěkujomy se za waš komentar!
+ Źěkujomy se za waš komentar!Wjelgin spokojom
@@ -2754,6 +2718,14 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt
Wjelgin njespokojom
+
+
+ Napšašowanje wócyniś
+
+ Napšašowanje zacyniś
+
+ Zacyniś
+
Pśizjawjenja
diff --git a/mobile/android/fenix/app/src/main/res/values-el/strings.xml b/mobile/android/fenix/app/src/main/res/values-el/strings.xml
index ede381ca29..cf34620a47 100644
--- a/mobile/android/fenix/app/src/main/res/values-el/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-el/strings.xml
@@ -205,6 +205,10 @@
ΠρόσθεταΕπεκτάσεις
+
+ Διαχείριση επεκτάσεων
+
+ Ανακαλύψτε περισσότερες επεκτάσειςΠληροφορίες λογαριασμού
@@ -223,6 +227,8 @@
Άνοιγμα σε κανονική καρτέλαΠροσθήκη στην αρχική οθόνη
+
+ Προσθήκη στην αρχική οθόνη…Εγκατάσταση
@@ -235,9 +241,13 @@
Μετάφραση σελίδας
+ Αποθήκευση σε συλλογή…
+
Αποθήκευση στη συλλογήΚοινή χρήση
+
+ Κοινή χρήση…Άνοιγμα σε %1$s
@@ -291,6 +301,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Αποθήκευση
+
+ Προσθήκη στους σελιδοδείκτες
+
+ Επεξεργασία σελιδοδείκτη
+
+ Αποθήκευση ως PDF…
+
+ Ενεργοποίηση προβολής ανάγνωσης
+
+ Απενεργοποίηση προβολής ανάγνωσης
+
+ Μετάφραση σελίδας…
+
+ Μεταφράστηκε σε %1$s
+
+ Εκτύπωση…
+
Δεν υπάρχουν επεκτάσεις
@@ -388,8 +416,6 @@
Σημείωση απορρήτου του Firefox
-
- Μάθετε περισσότερα στη σημείωση απορρήτου μαςΜας αρέσει να σας προστατεύουμεΓλώσσα
- Μετάφραση
+ Μετάφραση
+
+ ΜεταφράσειςΕπιλογές δεδομένων
@@ -672,10 +700,6 @@
ΑπαιτείταιΠροαιρετικό
-
- Ανάγνωση και αλλαγή δεδομένων ιστοτόπων
-
- Διαγραφή ιστοτόπουΑποδοχή για όλους τους ιστοτόπους
@@ -804,8 +828,6 @@
ΙστορικόΣελιδοδείκτες
-
- ΣυνδέσειςΚωδικοί πρόσβασης
@@ -832,8 +854,6 @@
and the third is the device model. -->
%1$s στο %2$s %3$s
-
- Πιστωτικές κάρτεςΜέθοδοι πληρωμής
@@ -849,6 +869,14 @@
Καρτέλα από %s
+
+
+ Έκλεισαν %2$d καρτέλες του %1$s
+
+ Προβολή πρόσφατα κλεισμένων καρτελών
+
Εξαιρέσεις
@@ -1784,13 +1812,9 @@
Μπορείτε εύκολα να προσθέσετε αυτόν τον ιστότοπο στην αρχική οθόνη για άμεση πρόσβαση και ταχύτερη περιήγηση, σαν να ήταν εφαρμογή.
-
- Συνδέσεις και κωδικοί πρόσβασηςΚωδικοί πρόσβασης
- Αποθήκευση συνδέσεων και κωδικών πρόσβασης
-
Αποθήκευση κωδικών πρόσβασηςΕρώτηση για αποθήκευση
@@ -1806,46 +1830,27 @@
Συμπλήρωση στοιχείων σύνδεσης σε άλλες εφαρμογές της συσκευής σας.
-
- Προσθήκη σύνδεσης
-
Προσθήκη κωδικού πρόσβασης
-
- Συγχρονισμός συνδέσεωνΣυγχρονισμός κωδικών πρόσβασης
-
- Συγχρονισμός συνδέσεων μεταξύ συσκευώνΣυγχρονισμός κωδικών πρόσβασης μεταξύ των συσκευών σας
-
- Αποθηκευμένες συνδέσειςΑποθηκευμένοι κωδικοί πρόσβασης
- Οι συνδέσεις που αποθηκεύετε ή συγχρονίζετε στο %s θα εμφανίζονται εδώ.
-
Οι κωδικοί πρόσβασης που αποθηκεύετε ή συγχρονίζετε στο %s θα εμφανίζονται εδώ. Όλοι οι κωδικοί πρόσβασης που αποθηκεύετε κρυπτογραφούνται.
-
- Μάθετε περισσότερα σχετικά με το Sync.Μάθετε περισσότερα σχετικά με τον συγχρονισμόΕξαιρέσεις
-
- Εδώ εμφανίζονται οι συνδέσεις και οι κωδικοί πρόσβασης που δεν αποθηκεύονται.Το %s δεν θα αποθηκεύει κωδικούς πρόσβασης για τους ιστοτόπους που αναφέρονται εδώ.
-
- Δεν θα αποθηκεύονται στοιχεία σύνδεσης για τους εξής ιστοτόπους.Το %s δεν θα αποθηκεύει κωδικούς πρόσβασης για αυτούς τους ιστοτόπους.Διαγραφή όλων των εξαιρέσεων
-
- Αναζήτηση συνδέσεωνΑναζήτηση κωδικών πρόσβασης
@@ -1874,17 +1879,11 @@
Εμφάνιση κωδικού πρόσβασηςΑπόκρυψη κωδικού πρόσβασης
-
- Ξεκλειδώστε για να δείτε τις αποθηκευμένες συνδέσεις σαςΞεκλειδώστε για να δείτε τους αποθηκευμένους κωδικούς πρόσβασής σας
- Προστασία στοιχείων σύνδεσης
-
Προστασία των αποθηκευμένων κωδικών πρόσβασής σας
- Ορίστε ένα μοτίβο κλειδώματος συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για προστασία των αποθηκευμένων στοιχείων σύνδεσης, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας.
-
Ορίστε ένα μοτίβο κλειδώματος συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για την προστασία των αποθηκευμένων κωδικών πρόσβασής σας, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας.Αργότερα
@@ -1901,9 +1900,6 @@
Τελευταία χρήση
-
- Ταξινόμηση μενού σύνδεσης
-
Μενού ταξινόμησης κωδικών πρόσβασης
@@ -1912,42 +1908,28 @@
Αυτόματη συμπλήρωσηΔιευθύνσεις
-
- Πιστωτικές κάρτεςΜέθοδοι πληρωμής
- Αποθήκευση και αυτόματη συμπλήρωση στοιχείων καρτών
-
Αποθήκευση και συμπλήρωση μεθόδων πληρωμής
-
- Τα δεδομένα κρυπτογραφούνταιΤο %s κρυπτογραφεί όλες τις μεθόδους πληρωμής που αποθηκεύετεΣυγχρονισμός καρτών μεταξύ συσκευώνΣυγχρονισμός καρτών
-
- Προσθήκη πιστωτικής κάρταςΠροσθήκη κάρτας
-
- Διαχείριση αποθηκευμένων καρτώνΔιαχείριση καρτώνΠροσθήκη διεύθυνσηςΔιαχείριση διευθύνσεων
-
- Αποθήκευση και αυτόματη συμπλήρωση διευθύνσεωνΑποθήκευση και συμπλήρωση διευθύνσεων
-
- Συμπεριλάβετε πληροφορίες, όπως αριθμούς, email και διευθύνσεις αποστολήςΠεριλαμβάνει αριθμούς τηλεφώνου και διευθύνσεις email
@@ -1971,8 +1953,6 @@
Διαγραφή κάρτας
- Θέλετε σίγουρα να διαγράψετε αυτήν την πιστωτική κάρτα;
-
Διαγραφή κάρτας;Διαγραφή
@@ -1986,24 +1966,15 @@
Αποθηκευμένες κάρτες
-
- Παρακαλώ εισαγάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας
-
Εισαγάγετε έγκυρο αριθμό κάρτας
-
- Παρακαλώ συμπληρώστε αυτό το πεδίοΠροσθήκη ονόματοςΞεκλειδώστε για να δείτε τις αποθηκευμένες κάρτες σας
- Ασφαλίστε τις πιστωτικές κάρτες σας
-
Προστασία των αποθηκευμένων μεθόδων πληρωμής σας
- Ορίστε ένα μοτίβο κλειδώματος συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για την προστασία των αποθηκευμένων πιστωτικών καρτών σας, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας.
-
Ορίστε ένα μοτίβο κλειδώματος της συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για την προστασία των αποθηκευμένων καρτών σας, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας.Ρύθμιση τώρα
@@ -2012,8 +1983,6 @@
Ξεκλειδώστε τη συσκευή σας
-
- Ξεκλειδώστε για χρήση των στοιχείων πιστωτικής κάρταςΞεκλειδώστε για χρήση των αποθηκευμένων μεθόδων πληρωμής
@@ -2023,12 +1992,6 @@
Επεξεργασία διεύθυνσηςΔιαχείριση διευθύνσεων
-
- Όνομα
-
- Μεσαίο όνομα
-
- ΕπώνυμοΌνομα
@@ -2054,8 +2017,6 @@
Διαγραφή διεύθυνσης
-
- Θέλετε σίγουρα να διαγράψετε αυτήν τη διεύθυνση;Διαγραφή διεύθυνσης;
@@ -2157,49 +2118,29 @@
ΔιαγραφήΕπεξεργασία
-
- Θέλετε σίγουρα να διαγράψετε αυτή τη σύνδεση;Θέλετε σίγουρα να διαγράψετε αυτόν τον κωδικό πρόσβασης;ΔιαγραφήΑκύρωση
-
- Επιλογές σύνδεσηςΕπιλογές κωδικών πρόσβασης
-
- Το επεξεργάσιμο πεδίο κειμένου της διεύθυνσης ιστού της σύνδεσης.Το επεξεργάσιμο πεδίο κειμένου της διεύθυνσης ιστοτόπου.
-
- Το επεξεργάσιμο πεδίο κειμένου για το όνομα χρήστη της σύνδεσης.Το επεξεργάσιμο πεδίο κειμένου για το όνομα χρήστη.
- Το επεξεργάσιμο πεδίο κειμένου για τον κωδικό πρόσβασης της σύνδεσης.
-
Το επεξεργάσιμο πεδίο κειμένου για τον κωδικό πρόσβασης.
-
- Αποθήκευση αλλαγών στη σύνδεση.Αποθήκευση αλλαγών.
-
- ΕπεξεργασίαΕπεξεργασία κωδικού πρόσβασης
-
- Προσθήκη νέας σύνδεσηςΠροσθήκη κωδικού πρόσβασης
-
- Απαιτείται κωδικός πρόσβασηςΕισαγάγετε έναν κωδικό πρόσβασης
- Απαιτείται όνομα χρήστη
-
Εισαγάγετε ένα όνομα χρήστηΑπαιτείται όνομα κεντρικού υπολογιστή
@@ -2548,6 +2489,8 @@
Όχι τώραΕμφάνιση πρωτότυπου
+
+ Φορτώθηκε η αρχική, αμετάφραστη σελίδαΤέλος
@@ -2605,6 +2548,9 @@
Κλείσιμο σελίδας μεταφράσεων
+
+ Ορισμένες ρυθμίσεις δεν είναι προσωρινά διαθέσιμες.
+
Μεταφράσεις
@@ -2628,6 +2574,9 @@
Επιλέξτε μια γλώσσα για να διαχειριστείτε τις προτιμήσεις «πάντα μετάφραση» και «ποτέ μετάφραση».
+
+ Δεν ήταν δυνατή η φόρτωση των γλωσσών. Ελέγξτε ξανά αργότερα.
+
Πρόταση για μετάφραση (προεπιλογή)
@@ -2651,6 +2600,8 @@
Αφαίρεση %1$s
+
+ Δεν ήταν δυνατή η φόρτωση των ιστοτόπων. Ελέγξτε ξανά αργότερα.Διαγραφή του %1$s;
@@ -2728,13 +2679,18 @@
Πλοήγηση προς τα πίσω
+
+ Άνοιγμα μενού εντοπισμού σφαλμάτων
+
Εργαλεία καρτελώνΑριθμός καρτελών
- Ενεργές
+ Ενεργές
+
+ ΕνεργέςΑνενεργές
@@ -2745,6 +2701,16 @@
Εργαλείο δημιουργίας καρτελώνΠλήθος καρτελών προς δημιουργία
+
+ Το πεδίο κειμένου είναι κενό
+
+ Παρακαλώ εισαγάγετε μόνο θετικούς ακέραιους αριθμούς
+
+ Παρακαλώ εισαγάγετε έναν αριθμό μεγαλύτερο του μηδέν
+
+ Υπέρβαση του μέγιστου αριθμού καρτελών (%1$s) που μπορούν να δημιουργηθούν με μία ενέργειαΠροσθήκη στις ενεργές καρτέλες
@@ -2761,11 +2727,11 @@
Σημείωση απορρήτου
- Υποβολή
+ Υποβολή
- Κλείσιμο
+ Κλείσιμο
- Ευχαριστούμε για τα σχόλιά σας!
+ Ευχαριστούμε για τα σχόλιά σας!Πολύ ικανοποιημένος/-η
@@ -2778,6 +2744,14 @@
Πολύ δυσαρεστημένος/-η
+
+
+ Άνοιγμα έρευνας
+
+ Κλείσιμο έρευνας
+
+ Κλείσιμο
+
Συνδέσεις
diff --git a/mobile/android/fenix/app/src/main/res/values-en-rCA/strings.xml b/mobile/android/fenix/app/src/main/res/values-en-rCA/strings.xml
index 5ec62ac882..dac62c0821 100644
--- a/mobile/android/fenix/app/src/main/res/values-en-rCA/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-en-rCA/strings.xml
@@ -200,6 +200,10 @@
Add-onsExtensions
+
+ Manage extensions
+
+ Discover more extensionsAccount info
@@ -218,6 +222,8 @@
Open in regular tabAdd to Home screen
+
+ Add to Home screen…Install
@@ -229,9 +235,13 @@
Translate page
+ Save to collection…
+
Save to collectionShare
+
+ Share…Open in %1$s
@@ -283,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Save
+
+ Bookmark this page
+
+ Edit bookmark
+
+ Save as PDF…
+
+ Turn on Reader View
+
+ Turn off Reader View
+
+ Translate page…
+
+ Translated to %1$s
+
+ Print…
+
No extensions here
@@ -377,8 +405,6 @@
Firefox privacy notice
-
- Learn more in our privacy noticeWe love keeping you safeLanguage
- Translation
+ Translation
+
+ TranslationsData choices
@@ -658,10 +686,6 @@
RequiredOptional
-
- Read and change website data
-
- Delete websiteAllow for all sites
@@ -787,8 +811,6 @@
HistoryBookmarks
-
- LoginsPasswords
@@ -815,8 +837,6 @@
and the third is the device model. -->
%1$s on %2$s %3$s
-
- Credit cardsPayment methods
@@ -832,6 +852,14 @@
Tab from %s
+
+
+ %1$s tabs closed: %2$d
+
+ View recently closed tabs
+
Exceptions
@@ -1750,13 +1778,9 @@
You can easily add this website to your device’s Home screen to have instant access and browse faster with an app-like experience.
-
- Logins and passwordsPasswords
- Save logins and passwords
-
Save passwordsAsk to save
@@ -1771,46 +1795,27 @@
Fill usernames and passwords in other apps on your device.
-
- Add login
-
Add password
-
- Sync loginsSync passwords
-
- Sync logins across devicesSync passwords across devices
-
- Saved loginsSaved passwords
- The logins you save or sync to %s will show up here.
-
The passwords you save or sync to %s will be listed here. All passwords you save are encrypted.
-
- Learn more about Sync.Learn more about syncExceptions
-
- Logins and passwords that are not saved will be shown here.%s won’t save passwords for sites listed here.
-
- Logins and passwords will not be saved for these sites.%s won’t save passwords for these sites.Delete all exceptions
-
- Search loginsSearch passwords
@@ -1839,17 +1844,11 @@
Show passwordHide password
-
- Unlock to view your saved loginsUnlock to view your saved passwords
- Secure your logins and passwords
-
Secure your saved passwords
- Set up a device lock pattern, PIN, or password to protect your saved logins and passwords from being accessed if someone else has your device.
-
Set up a device lock pattern, PIN, or password to protect your saved passwords from being accessed if someone else has your device.Later
@@ -1866,8 +1865,6 @@
Name (A-Z)Last used
-
- Sort logins menuSort passwords menu
@@ -1877,29 +1874,19 @@
AutofillAddresses
-
- Credit cardsPayment methods
- Save and autofill cards
-
Save and fill payment methods
-
- Data is encrypted%s encrypts all payment methods you saveSync cards across devicesSync cards
-
- Add credit cardAdd card
-
- Manage saved cardsManage cards
@@ -1907,12 +1894,8 @@
Manage addresses
-
- Save and autofill addressesSave and fill addresses
-
- Include information like numbers, email and shipping addressesIncludes phone numbers and email addresses
@@ -1936,8 +1919,6 @@
Delete card
- Are you sure you want to delete this credit card?
-
Delete card?Delete
@@ -1951,24 +1932,15 @@
Saved cards
-
- Please enter a valid credit card number
-
Enter a valid card number
-
- Please fill out this fieldAdd a nameUnlock to view your saved cards
- Secure your credit cards
-
Secure your saved payment methods
- Set up a device lock pattern, PIN, or password to protect your saved credit cards from being accessed if someone else has your device.
-
Set up a device lock pattern, PIN, or password to protect your saved payment methods from being accessed if someone else has your device.Set up now
@@ -1976,8 +1948,6 @@
LaterUnlock your device
-
- Unlock to use stored credit card informationUnlock to use saved payment methods
@@ -1987,12 +1957,6 @@
Edit addressManage addresses
-
- First Name
-
- Middle Name
-
- Last NameName
@@ -2018,8 +1982,6 @@
Delete address
-
- Are you sure you want to delete this address?Delete this address?
@@ -2118,49 +2080,29 @@
DeleteEdit
-
- Are you sure you want to delete this login?Are you sure you want to delete this password?DeleteCancel
-
- Login optionsPassword options
-
- The editable text field for the web address of the login.The editable text field for the website address.
-
- The editable text field for the username of the login.The editable text field for the username.
- The editable text field for the password of the login.
-
The editable text field for the password.
-
- Save changes to login.Save changes.
-
- EditEdit password
-
- Add new loginAdd password
-
- Password requiredEnter a password
- Username required
-
Enter a usernameHostname required
@@ -2566,6 +2508,9 @@
Close Translations sheet
+
+ Some settings are temporarily unavailable.
+
Translations
@@ -2588,6 +2533,9 @@
Select a language to manage ”always translate“ and ”never translate“ preferences.
+
+ Couldn’t load languages. Please check back later.
+
Offer to translate (default)
@@ -2610,6 +2558,8 @@
Remove %1$s
+
+ Couldn’t load sites. Please check back later.Delete %1$s?
@@ -2687,13 +2637,18 @@
Navigate back
+
+ Open debug drawer
+
Tab ToolsTab count
- Active
+ Active
+
+ ActiveInactive
@@ -2704,6 +2659,16 @@
Tab creation toolTab quantity to create
+
+ Text field is empty
+
+ Please enter positive integers only
+
+ Please enter a number greater than zero
+
+ Exceeded the maximum number of tabs (%1$s) that can be generated in one operationAdd to active tabs
@@ -2720,11 +2685,11 @@
Privacy Notice
- Submit
+ Submit
- Close
+ Close
- Thanks for your feedback!
+ Thanks for your feedback!Very Satisfied
@@ -2736,6 +2701,14 @@
Very Dissatisfied
+
+
+ Open survey
+
+ Close survey
+
+ Close
+
Logins
diff --git a/mobile/android/fenix/app/src/main/res/values-en-rGB/strings.xml b/mobile/android/fenix/app/src/main/res/values-en-rGB/strings.xml
index b04058b493..8b41ad2e50 100644
--- a/mobile/android/fenix/app/src/main/res/values-en-rGB/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-en-rGB/strings.xml
@@ -198,6 +198,10 @@
Add-onsExtensions
+
+ Manage extensions
+
+ Discover more extensionsAccount info
@@ -216,6 +220,8 @@
Open in regular tabAdd to Home screen
+
+ Add to Home screen…Install
@@ -227,9 +233,13 @@
Translate page
+ Save to collection…
+
Save to collectionShare
+
+ Share…Open in %1$s
@@ -283,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Save
+
+ Bookmark this page
+
+ Edit bookmark
+
+ Save as PDF…
+
+ Turn on Reader View
+
+ Turn off Reader View
+
+ Translate page…
+
+ Translated to %1$s
+
+ Print…
+
No extensions here
@@ -379,8 +407,6 @@
Firefox privacy notice
-
- Learn more in our privacy noticeWe love keeping you safeLanguage
- Translation
+ Translation
+
+ TranslationsData choices
@@ -662,10 +690,6 @@
RequiredOptional
-
- Read and change web site data
-
- Delete web siteAllow for all sites
@@ -790,8 +814,6 @@
HistoryBookmarks
-
- LoginsPasswords
@@ -818,8 +840,6 @@
and the third is the device model. -->
%1$s on %2$s %3$s
-
- Credit cardsPayment methods
@@ -835,6 +855,14 @@
Tab from %s
+
+
+ %1$s tabs closed: %2$d
+
+ View recently closed tabs
+
Exceptions
@@ -1755,13 +1783,9 @@
You can easily add this web site to your device’s Home screen to have instant access and browse faster with an app-like experience.
-
- Logins and passwordsPasswords
- Save logins and passwords
-
Save passwordsAsk to save
@@ -1777,47 +1801,28 @@
Fill usernames and passwords in other apps on your device.
-
- Add login
-
Add password
-
- Synchronise loginsSynchronise passwords
-
- Synchronise logins across devicesSynchronise passwords across devices
-
- Saved loginsSaved passwords
- The logins you save or synchronise to %s will show up here.
-
The passwords you save or synchronise to %s will be listed here. All passwords you save are encrypted.
-
- Learn more about Sync.Learn more about SyncExceptions
-
- Logins and passwords that are not saved will be shown here.%s won’t save passwords for sites listed here.
-
- Logins and passwords will not be saved for these sites.%s won’t save passwords for these sites.Delete all exceptions
-
- Search loginsSearch passwords
@@ -1846,17 +1851,11 @@
Show passwordHide password
-
- Unlock to view your saved loginsUnlock to view your saved passwords
- Secure your logins and passwords
-
Secure your saved passwords
- Set up a device lock pattern, PIN, or password to protect your saved logins and passwords from being accessed if someone else has your device.
-
Set up a device lock pattern, PIN, or password to protect your saved passwords from being accessed if someone else has your device.Later
@@ -1873,8 +1872,6 @@
Name (A-Z)Last used
-
- Sort logins menuSort passwords menu
@@ -1884,41 +1881,27 @@
AutofillAddresses
-
- Credit cardsPayment methods
- Save and autofill cards
-
Save and fill payment methods
-
- Data is encrypted%s encrypts all payment methods you saveSynchronise cards across devicesSynchronise cards
-
- Add credit cardAdd card
-
- Manage saved cardsManage cardsAdd addressManage addresses
-
- Save and autofill addressesSave and fill addresses
-
- Include information like numbers, email and shipping addressesIncludes phone numbers and email addresses
@@ -1942,8 +1925,6 @@
Delete card
- Are you sure you want to delete this credit card?
-
Delete card?Delete
@@ -1957,24 +1938,15 @@
Saved cards
-
- Please enter a valid credit card number
-
Enter a valid card number
-
- Please fill out this fieldAdd a nameUnlock to view your saved cards
- Secure your credit cards
-
Secure your saved payment methods
- Set up a device lock pattern, PIN, or password to protect your saved credit cards from being accessed if someone else has your device.
-
Set up a device lock pattern, PIN, or password to protect your saved payment methods from being accessed if someone else has your device.Set up now
@@ -1982,8 +1954,6 @@
LaterUnlock your device
-
- Unlock to use stored credit card informationUnlock to use saved payment methods
@@ -1993,12 +1963,6 @@
Edit addressManage addresses
-
- First Name
-
- Middle Name
-
- Last NameName
@@ -2024,8 +1988,6 @@
Delete address
-
- Are you sure you want to delete this address?Delete this address?
@@ -2124,49 +2086,29 @@
DeleteEdit
-
- Are you sure you want to delete this login?Are you sure you want to delete this password?DeleteCancel
-
- Login optionsPassword options
-
- The editable text field for the web address of the login.The editable text field for the web site address.
-
- The editable text field for the username of the login.The editable text field for the username.
- The editable text field for the password of the login.
-
The editable text field for the password.
-
- Save changes to login.Save changes.
-
- EditEdit password
-
- Add new loginAdd password
-
- Password requiredEnter a password
- Username required
-
Enter a usernameHostname required
@@ -2513,6 +2455,8 @@
Not nowShow original
+
+ Original untranslated page loadedDone
@@ -2570,6 +2514,9 @@
Close Translations sheet
+
+ Some settings are temporarily unavailable.
+
Translations
@@ -2592,6 +2539,9 @@
Select a language to manage ”always translate“ and ”never translate“ preferences.
+
+ Couldn’t load languages. Please check back later.
+
Offer to translate (default)
@@ -2614,6 +2564,8 @@
Remove %1$s
+
+ Couldn’t load sites. Please check back later.Delete %1$s?
@@ -2691,13 +2643,18 @@
Navigate backwards
+
+ Open debug drawer
+
Tab ToolsTab count
- Active
+ Active
+
+ ActiveInactive
@@ -2708,6 +2665,16 @@
Tab creation toolTab quantity to create
+
+ Text field is empty
+
+ Please enter positive integers only
+
+ Please enter a number greater than zero
+
+ Exceeded the maximum number of tabs (%1$s) that can be generated in one operationAdd to active tabs
@@ -2724,11 +2691,11 @@
Privacy Notice
- Submit
+ Submit
- Close
+ Close
- Thanks for your feedback!
+ Thanks for your feedback!Very Satisfied
@@ -2740,6 +2707,14 @@
Very Dissatisfied
+
+
+ Open survey
+
+ Close survey
+
+ Close
+
Logins
diff --git a/mobile/android/fenix/app/src/main/res/values-eo/strings.xml b/mobile/android/fenix/app/src/main/res/values-eo/strings.xml
index 0b365e2616..962dc6a81c 100644
--- a/mobile/android/fenix/app/src/main/res/values-eo/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-eo/strings.xml
@@ -48,11 +48,19 @@
- Ĵuse konservitaj
+ Ĵuse konservitaj
- Montri ĉiujn konservitajn legosignojn
+ Montri ĉiujn konservitajn legosignojn
- Forigi
+ Forigi
+
+
+
+ Legosignoj
+
+ Montri ĉiujn legosignojn
+
+ Forigi%1$s estas kreita de Mozilla.
@@ -140,8 +148,10 @@
Nova privata langeto
-
- Ŝparvojo por la pasvortoj
+
+ Pasvortoj
+
+ Ŝparvojo por la pasvortoj
@@ -182,11 +192,13 @@
Haltigi
- Aldonaĵoj
+ Aldonaĵoj
+
+ EtendaĵojInformoj pri konto
- Neniu aldonaĵo estas ĉi tie
+ Neniu aldonaĵo estas ĉi tieHelpo
@@ -202,12 +214,14 @@
Aldoni al hejmekrano
- Instali
+ InstaliRespeguliSerĉi en paĝo
+
+ Serĉi en paĝo…Traduki paĝon
@@ -240,6 +254,33 @@
Personecigi ekan paĝon
+
+ Komenci seancon
+
+ Speguli pasvortojn, langetojn, kaj pli
+
+ Rekomencu seancon por speguli
+
+ Spegulado paŭzinta
+
+ Nova privata langeto
+
+ Pasvortoj
+
+ Novaĵoj en %1$s
+
+ Iri al versio por komputiloj
+
+ Iloj
+
+ Konservi
+
+
+
+ Ne estas etendaĵoj ĉi tie
+
Hejmekrano
@@ -543,6 +584,8 @@
Rekonektiĝu por daŭrigi la speguladonLingvo
+
+ TradukoElekto de datumoj
@@ -594,10 +637,14 @@
Fino de programo pro apliko de ŝanĝoj…
- Aldonaĵoj
+ Aldonaĵoj
+
+ Etendaĵoj
- Instali aldonaĵon el dosiero
+ Instali aldonaĵon el dosiero
+
+ Instali etendaĵon el dosieroSciigoj
@@ -606,9 +653,25 @@
Ne permesita
+
+
+ Postulata
+
+ Elektebla
+
+ Legi kaj ŝanĝi retejajn datumojn
+
+ Forigi retejon
+
+ Permesi por ĉiuj retejoj
+
+ Se vi fidas tiun ĉi etendaĵon vi povas doni al ĝi tiun permeson por ĉiuj retejoj.
+
- Personecigita kolekto de aldonaĵoj
+ Personecigita kolekto de aldonaĵoj
+
+ Personecigita kolekto de etendaĵojAkcepti
@@ -618,13 +681,18 @@
Posedanto de kolekto (identigilo de uzanto)
- La kolekto de aldonaĵoj estis ŝanĝita. La programo nun finiĝos por apliki la ŝanĝojn…
+ La kolekto de aldonaĵoj estis ŝanĝita. La programo nun finiĝos por apliki la ŝanĝojn…
+
+
+ La kolekto de etendaĵoj estis ŝanĝita. La programo nun finiĝos por apliki la ŝanĝojn…Reiri
- Ĵusaj legosignoj
+ Ĵusaj legosignoj
+
+ LegosignojĴusaj retpaĝoj
@@ -674,21 +742,37 @@
- Novaj aldonaĵoj disponeblaj
+ Novaj aldonaĵoj disponeblaj
+
+ Novaj etendaĵoj disponeblajKonu pli ol 100+ novajn etendaĵojn, kiuj permesas al vi personecigi Firefox.
- Esplori aldonaĵojn
+ Esplori aldonaĵojn
-
+
+ Esplori etendaĵoj
+
+
- La aldonaĵoj estas provizore malaktivigitaj
+ La aldonaĵoj estas provizore malaktivigitaj
+
+ La etendaĵoj estas provizore malaktivigitaj
- Unu aŭ pli da aldonaĴoj ĉesis funkcii, kaj tio igas vian sistemon nestabila. %1$s malsukcese klopodis restartigi la aldonaĵo(j)n.\n\nAldonaĵoj ne estos restartigitaj dum via nuna seanco.\n\nForigo aŭ malaktivigo de aldonaĵo(j) povus solvi tiun ĉi problemo.
+ Unu aŭ pli da aldonaĴoj ĉesis funkcii, kaj tio igas vian sistemon nestabila. %1$s malsukcese klopodis restartigi la aldonaĵo(j)n.\n\nAldonaĵoj ne estos restartigitaj dum via nuna seanco.\n\nForigo aŭ malaktivigo de aldonaĵo(j) povus solvi tiun ĉi problemo.
+
+ Unu aŭ pli da etendaĵoj ĉesis funkcii, kaj tio igas vian sistemon nestabila. %1$s malsukcese klopodis restartigi la etendaĵo(j)n.\n\nEtendaĵoj ne estos restartigitaj dum via nuna seanco.\n\nForigo aŭ malaktivigo de aldonaĵo(j) povus solvi tiun ĉi problemo.
- Provi restartigi aldonaĵojn
+ Provi restartigi aldonaĵojn
+
+ Provi restartigi etendaĵojn
- Daŭrigi kun aldonaĵoj malaktivigitaj
+ Daŭrigi kun aldonaĵoj malaktivigitaj
+
+
+ Daŭrigi kun etendaĵoj malaktivigitaj
@@ -2441,10 +2525,14 @@
Traduki elTraduki en
+
+ Provi alian originan lingvonNe nunMontri originalon
+
+ Originala netradukita paĝo ŝargitaFarita
@@ -2464,7 +2552,7 @@
Bedaŭrinde ni ankoraŭ ne subtenas %1$s.
- Pli da informo
+ Pli da informo
@@ -2478,7 +2566,9 @@
- Tradukaj elektebloj
+ Tradukaj elektebloj
+
+ Tradukaj elekteblojĈiam proponi tradukon
@@ -2496,6 +2586,9 @@
Pri tradukoj en %1$s
+
+ Fermi panelon de tradukoj
+
Tradukoj
@@ -2603,6 +2696,8 @@
Ĉu elŝuti dum datumŝpara reĝimo (%1$s)?Ni elŝutas partojn de lingvoj al via staplo por gardi viajn tradukojn privataj.
+
+ Ni elŝutas partojn de lingvoj por gardi viajn tradukojn privataj.Ĉiam elŝuti en datumŝpara regïmo
@@ -2617,6 +2712,8 @@
Erarserĉilaj ilojIri reen
+
+
Langetaj iloj
@@ -2639,4 +2736,39 @@
Aldoni al malaktivaj langetojAldoni al privataj langetoj
+
+
+
+
+ Daŭrigi
+
+ Respondi tiun ĉi demandaron
+
+ Rimarko pri privateco
+
+ Sendi
+
+ Fermi
+
+ Dankon pro via opinio!
+
+ Tre kontentiga
+
+ Kontentiga
+
+ Neŭtra
+
+ Nekontentiga
+
+ Tute nekontentiga
+
+
+
+ Legitimiloj
+
+ Nuna nomregno: %s
+
+ Aldoni neveran konton al tiu ĉi nomregno
+
+ Forigi legitimilon kun la nomo de uzanto %s
diff --git a/mobile/android/fenix/app/src/main/res/values-es-rAR/strings.xml b/mobile/android/fenix/app/src/main/res/values-es-rAR/strings.xml
index 785d99207d..ad85fcab17 100644
--- a/mobile/android/fenix/app/src/main/res/values-es-rAR/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-es-rAR/strings.xml
@@ -201,6 +201,10 @@
ComplementosExtensiones
+
+ Administrar extensiones
+
+ Descubrir más extensionesInformación de la cuenta
@@ -219,6 +223,8 @@
Abrir en una pestaña normalAgregar a pantalla de inicio
+
+ Agregar a la pantalla de inicio…Instalar
@@ -230,9 +236,13 @@
Traducir página
+ Guardar en la colección…
+
Guardar en la colecciónCompartir
+
+ Compartir…Abrir en %1$s
@@ -287,6 +297,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Guardar
+
+ Marcar esta página
+
+ Editar marcador
+
+ Guardar como PDF…
+
+ Activar vista de lectura
+
+ Desactivar vista de lectura
+
+ Traducir página…
+
+ Traducido al %1$s
+
+ Imprimir…
+
No hay extensiones aquí
@@ -387,8 +415,6 @@
Aviso de privacidad de Firefox
-
- Conocé más en nuestra nota de privacidadNos encanta mantenerte seguroIdioma
- Traducción
+ Traducción
+
+ TraduccionesElección de datos
@@ -670,10 +698,6 @@
NecesariosOpcional
-
- Leer y cambiar los datos de sitios web
-
- Eliminar sitio webPermitir para todos los sitios
@@ -798,8 +822,6 @@
HistorialMarcadores
-
- Inicios de sesiónContraseñas
@@ -828,8 +850,6 @@
and the third is the device model. -->
%1$s en %2$s %3$s
-
- Tarjetas de créditoMétodos de pago
@@ -845,6 +865,14 @@
Pestaña de %s
+
+
+ Pestañas cerradas en %1$s: %2$d
+
+ Ver pestañas cerradas recientemente
+
Excepciones
@@ -1786,13 +1814,9 @@
Podés agregar este sitio a la pantalla de inicio del dispositivo fácilmente para tener acceso instantáneo y navegar más rápido con una experiencia similar a la de una aplicación.
-
- Inicios de sesión y contraseñasContraseñas
- Guardar inicios de sesión y contraseñas
-
Guardar contraseñasSolicitar guardar
@@ -1807,46 +1831,27 @@
Completar nombres de usuario y contraseñas en otras aplicaciones de tu dispositivo.
-
- Agregar inicio de sesión
-
Agregar contraseña
-
- Sincronizar inicios de sesiónSincronizar contraseñas
-
- Sincronizar inicios de sesión entre dispositivosSincronizar contraseñas entre dispositivos
-
- Inicios de sesión guardadosContraseñas guardadas
- Aquí se van a ver los inicios de sesión que guardes o sincronices con %s.
-
Las contraseñas que guardés o sincronicés con %s aparecerán acá. Todas las contraseñas que guardés están encriptadas.
-
- Conocé más acerca de Sync.Conocé más acerca de la sincronizaciónExcepciones
-
- Los inicios de sesión y las contraseñas que no se guardan se mostrarán aquí.%s no guardará las contraseñas de los sitios listados acá.
-
- Los inicios de sesión y las contraseñas no se van a guardar para estos sitios.%s no guardará las contraseñas de estos sitios.Eliminar todas las excepciones
-
- Buscar inicios de sesiónBuscar contraseñas
@@ -1875,17 +1880,11 @@
Mostrar contraseñaOcultar contraseña
-
- Desbloqueá para ver tus inicios de sesión guardadosDesbloqueá para ver las contraseñas guardadas
- Asegurá inicios de sesión y contraseñas
-
Asegurá tus contraseñas guardadas
- Configurá un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus inicios de sesión y contraseñas guardadas por si alguien más tiene tu dispositivo.
-
Configurá un patrón de bloqueo del dispositivo, PIN o contraseña para proteger el acceso a tus contraseñas guardadas si alguien más tiene tu dispositivo.Más tarde
@@ -1902,8 +1901,6 @@
Nombre (A-Z)Usado por última vez
-
- Ordenar menú de inicio de sesiónMenú ordenar contraseñas
@@ -1913,41 +1910,27 @@
AutocompletarDirecciones
-
- Tarjetas de créditoMétodos de pago
- Guardar y autocompletar tarjetas
-
Guardar y completar métodos de pago
-
- Los datos están cifrados%s cifra todos los métodos de pago guardadosSincronizar tarjetas entre dispositivosSincronizar tarjetas
-
- Agregar tarjeta de créditoAgregar tarjeta
-
- Administrar tarjetas guardadasAdministrar tarjetasAgregar direcciónAdministrar direcciones
-
- Guardar y autocompletar direccionesGuardar y completar direcciones
-
- Incluir información como números, correos electrónicos y direcciones de envíosIncluye números de teléfono y direcciones de correo electrónico
@@ -1971,8 +1954,6 @@
Borrar tarjeta
- ¿Estás seguro de querer borrar esta tarjeta de crédito?
-
¿Borrar tarjeta?Borrar
@@ -1986,25 +1967,16 @@
Tarjetas guardadas
-
- Ingresá un número de tarjeta de crédito válido
-
Ingresá un número de tarjeta válido
-
- Se debe completar este campoAgregar un nombreDesbloqueá para ver las tarjetas guardadas
-
- Asegurá tus tarjetas de créditoAsegurá tus métodos de pago guardados
- Configurá un patrón de bloqueo del dispositivo, PIN o contraseña para proteger el acceso a tus tarjetas de crédito guardadas si alguien más tiene tu dispositivo.
-
Configurá un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus métodos de pago guardados por si otra persona accede a tu dispositivo.Configurar ahora
@@ -2013,9 +1985,6 @@
Desbloqueá tu dispositivo
-
- Desbloquear para usar la información almacenada de la tarjeta de crédito
-
Desbloquear para usar los métodos de pago guardados
@@ -2024,12 +1993,6 @@
Editar direcciónAdministrar direcciones
-
- Primer Nombre
-
- Segundo nombre
-
- ApellidoNombre
@@ -2055,8 +2018,6 @@
Borrar dirección
-
- ¿Estás seguro de querer borrar esta dirección?¿Borrar esta dirección?
@@ -2157,49 +2118,29 @@
EliminarEditar
-
- ¿Estás seguro de que querés eliminar este inicio de sesión?¿Estás seguro de que querés eliminar esta contraseña?EliminarCancelar
-
- Opciones de inicio de sesiónOpciones de contraseña
-
- El campo de texto editable para la dirección web del inicio de sesión.El campo de texto editable para la dirección del sitio web.
-
- El campo de texto editable para el nombre de usuario del inicio de sesión.El campo de texto editable para el nombre de usuario.
- El campo de texto editable para la contraseña del inicio de sesión.
-
El campo de texto editable para la contraseña.
-
- Guardar cambios para el inicio de sesión.Guardar cambios.
-
- EditarEditar contraseña
-
- Agregar nuevo inicio de sesiónAgregar contraseña
-
- Se necesita contraseñaIngresar una contraseña
- Se requiere nombre de usuario
-
Ingresar un nombre de usuarioSe requiere nombre de host
@@ -2608,6 +2549,9 @@
Cerrar la hoja de traducciones
+
+ Algunas configuraciones no están disponibles temporariamente.
+
Traducciones
@@ -2630,6 +2574,9 @@
Seleccioná un idioma para administrar las preferencias de ”traducir siempre“ y ”nunca traducir“.
+
+ No se pudieron cargar los idiomas. Intentalo de nuevo más tarde.
+
Ofrecer traducción (predeterminado)
@@ -2653,6 +2600,8 @@
Eliminar %1$s
+
+ No se pudieron cargar los sitios. Intentalo de nuevo más tarde.¿Eliminar %1$s?
@@ -2730,13 +2679,18 @@
Navegar hacia atrás
+
+ Abrir cajón de depuración
+
Herramientas de pestañasCantidad de pestañas
- Activa
+ Activa
+
+ ActivoInactiva
@@ -2747,6 +2701,16 @@
Herramienta de creación de pestañasCantidad de pestañas a crear
+
+ El campo de texto está vacío
+
+ Ingresar solamente enteros positivos
+
+ Ingresar un número mayor que cero
+
+ Se superó el número máximo de pestañas (%1$s) que se pueden generar en una operaciónAgregar a pestañas activas
@@ -2763,11 +2727,11 @@
Nota de privacidad
- Enviar
+ Enviar
- Cerrar
+ Cerrar
- ¡Gracias por tus comentarios!
+ ¡Gracias por tus comentarios!Muy satisfecho
@@ -2779,6 +2743,14 @@
Muy insatisfecho
+
+
+ Abrir encuesta
+
+ Cerrar encuesta
+
+ Cerrar
+
Inicios de sesión
diff --git a/mobile/android/fenix/app/src/main/res/values-es-rCL/strings.xml b/mobile/android/fenix/app/src/main/res/values-es-rCL/strings.xml
index 099a7d1850..32f5170529 100644
--- a/mobile/android/fenix/app/src/main/res/values-es-rCL/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-es-rCL/strings.xml
@@ -47,12 +47,20 @@
- Guardados recientemente
+ Guardados recientemente
- Mostrar todos los marcadores guardados
+ Mostrar todos los marcadores guardados
- Eliminar
+ Eliminar
+
+
+
+ Marcadores
+
+ Mostrar todos los marcadores
+
+ Eliminar%1$s es producido por Mozilla.
@@ -191,6 +199,10 @@
ComplementosExtensiones
+
+ Gestionar extensiones
+
+ Descubrir más extensionesInformación de la cuenta
@@ -209,6 +221,8 @@
Abrir en pestaña normalAñadir a pantalla de inicio
+
+ Añadir a la pantalla de inicio…Instalar
@@ -220,9 +234,13 @@
Traducir página
+ Guardar en la colección…
+
Guardar en la colecciónCompartir
+
+ Compartir…Abrir en %1$s
@@ -275,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Guardar
+
+ Guardar esta página en marcadores
+
+ Editar marcador
+
+ Guardar como PDF…
+
+ Activar la vista de lector
+
+ Desactivar la vista de lector
+
+ Traducir página…
+
+ Traducido al %1$s
+
+ Imprimir…
+
No hay extensiones aquí
@@ -371,8 +407,6 @@
Aviso de privacidad de Firefox
-
- Aprende más en nuestra política de privacidadNos encanta mantenerte a salvoIdioma
- Traducción
+ Traducción
+
+ TraduccionesElección de datos
@@ -654,10 +690,6 @@
RequeridoOpcional
-
- Leer y cambiar datos del sitio web
-
- Eliminar sitio webPermitir para todos los sitios
@@ -686,7 +718,9 @@
Regresar a
- Marcadores recientes
+ Marcadores recientes
+
+ MarcadoresVisitados recientemente
@@ -781,8 +815,6 @@
HistorialMarcadores
-
- CredencialesContraseñas
@@ -809,8 +841,6 @@
and the third is the device model. -->
%1$s en %2$s %3$s
-
- Tarjetas de créditoMétodos de pago
@@ -826,6 +856,14 @@
Pestaña de %s
+
+
+ %1$s pestañas cerradas: %2$d
+
+ Ver pestañas cerradas recientemente
+
Excepciones
@@ -1749,13 +1787,9 @@
Puedes añadir fácilmente este sitio web a tu pantalla de inicio de tu dispositivo para tener acceso instantáneo y navegar rápidamente, consiguiendo una experiencia similar a la de una aplicación real.
-
- Credenciales y contraseñasContraseñas
- Guardar credenciales y contraseñas
-
Guardar contraseñasPreguntar si guardar
@@ -1770,47 +1804,28 @@
Completa los nombres de usuario y contraseñas en otras aplicaciones de tu dispositivo.
-
- Añadir conexión
-
Añadir contraseña
-
- Sincronizar credencialesSincronizar contraseñas
-
- Sincronizar credenciales en todos los dispositivosSincronizar contraseñas entre dispositivos
-
- Credenciales guardadasContraseñas guardadas
- Las credenciales que guardas o sincronizas con %s serán mostradas aquí.
-
Las contraseñas que guardes o sincronices con %s aparecerán aquí. Todas las contraseñas que guardes quedan cifradas.
-
- Aprender más acerca de Sync.Aprende más acerca de la sincronizaciónExcepciones
-
- Las credenciales y contraseñas que no son guardadas serán mostradas aquí.%s no guardará las contraseñas de los sitios listados aquí.
-
- Las credenciales y contraseñas no serán guardadas para estos sitios.%s no guardará las contraseñas para estos sitios.Eliminar todas las excepciones
-
- Buscar credencialesBuscar contraseñas
@@ -1839,17 +1854,11 @@
Mostrar contraseñaOcultar contraseña
-
- Desbloquea para ver tus credenciales guardadasDesbloquea para ver tus contraseñas guardadas
- Asegura tus credenciales y contraseñas
-
Asegura tus contraseñas guardadas
- Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus credenciales y contraseñas guardadas, y así no sean accedidas si alguien más tiene tu dispositivo.
-
Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus contraseñas guardadas, y así no sean accedidas si alguien más tiene tu dispositivo.Más tarde
@@ -1867,8 +1876,6 @@
Nombre (A-Z)Último uso
-
- Menú para ordenar credencialesMenú ordenar contraseñas
@@ -1878,41 +1885,27 @@
AutollenadoDirecciones
-
- Tarjetas de créditoMétodos de pago
- Guardar y autocompletar tarjetas
-
Guardar y completar métodos de pago
-
- Los datos están encriptados%s cifra todos los métodos de pago que guardasSincronizar tarjetas entre dispositivosSincronizar tarjetas
-
- Añadir tarjeta de créditoAñadir tarjeta
-
- Gestionar tarjetas guardadasGestionar tarjetasAñadir direcciónAdministrar direcciones
-
- Guardar y autocompletar direccionesGuardar y completar direcciones
-
- Incluye información como números, correos electrónicos y direccionesIncluye números de teléfono y direcciones de correo electrónico
@@ -1936,8 +1929,6 @@
Eliminar tarjeta
- ¿De verdad quieres eliminar esta tarjeta de crédito?
-
¿Eliminar tarjeta?Eliminar
@@ -1951,24 +1942,15 @@
Tarjetas guardadas
-
- Por favor, ingresa un número de tarjeta de crédito válido
-
Ingresa un número de tarjeta válido
-
- Complete este campoAñadir un nombreDesbloquea para ver tus tarjetas guardadas
- Asegura tus tarjetas de crédito
-
Asegura tus métodos de pago guardados
- Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus tarjetas de crédito guardadas, y así no sean accedidas si alguien más tiene tu dispositivo.
-
Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus métodos de pago guardados, y así no sean accedidos si alguien más tiene tu dispositivo.Configurar ahora
@@ -1976,8 +1958,6 @@
Más tardeDesbloquea tu dispositivo
-
- Desbloquea para usar información de la tarjeta de crédito almacenadaDesbloquea para usar métodos de pago guardados
@@ -1987,12 +1967,6 @@
Editar direcciónAdministrar direcciones
-
- Primer nombre
-
- Segundo nombre
-
- ApellidosNombre
@@ -2018,8 +1992,6 @@
Eliminar dirección
-
- ¿De verdad quieres eliminar esta dirección?¿Eliminar esta dirección?
@@ -2118,49 +2090,29 @@
EliminarEditar
-
- ¿De verdad quieres eliminar esta conexión?¿Estas seguro de eliminar esta contraseña?EliminarCancelar
-
- Opciones de credencialesOpciones de contraseña
-
- El campo de texto editable para la dirección web de la credencial.El campo de texto editable para la dirección del sitio web.
-
- El campo de texto editable para el nombre de usuario de la credencial.El campo de texto editable para el nombre de usuario.
- El campo de texto editable para la contraseña de la credencial.
-
El campo de texto editable para la contraseña.
-
- Guardar cambios a la credencial.Guardar cambios.
-
- EditarEditar contraseña
-
- Añadir nueva credencialAñadir contraseña
-
- Contraseña requeridaIngresar una contraseña
- Nombre de usuario requerido
-
Ingresar un nombre de usuarioNombre de servidor requerido
@@ -2508,6 +2460,8 @@
Ahora noMostrar original
+
+ Página original sin traducir cargadaHecho
@@ -2565,6 +2519,9 @@
Cerrar hoja de traducciones
+
+ Algunos ajustes no están disponibles temporalmente.
+
Traducciones
@@ -2587,6 +2544,9 @@
Selecciona un idioma para administrar las preferencias de ”traducir siempre“ y ”nunca traducir“.
+
+ No se pudieron cargar idiomas. Por favor, vuelve más tarde.
+
Ofrecer traducción (predeterminado)
@@ -2609,6 +2569,8 @@
Eliminar %1$s
+
+ No se pudieron cargar sitios. Por favor, vuelve más tarde.¿Eliminar %1$s?
@@ -2686,13 +2648,18 @@
Navegar hacia atrás
+
+ Abrir cajón de depuración
+
Herramientas de pestañaRecuento de pestañas
- Activa
+ Activa
+
+ ActivoInactiva
@@ -2703,6 +2670,16 @@
Herramienta de creación de pestañasCantidad de pestañas a crear
+
+ El campo de texto está vacío
+
+ Por favor, ingresa solo números enteros positivos
+
+ Por favor, introduce un número mayor que cero
+
+ Se superó el número máximo de pestañas (%1$s) que se pueden generar en una operaciónAñadir a pestañas activas
@@ -2719,11 +2696,11 @@
Política de privacidad
- Enviar
+ Enviar
- Cerrar
+ Cerrar
- ¡Gracias por tus comentarios!
+ ¡Gracias por tus comentarios!Muy satisfecho
@@ -2735,6 +2712,14 @@
Muy insatisfecho
+
+
+ Abrir encuesta
+
+ Cerrar encuesta
+
+ Cerrar
+
Conexiones
diff --git a/mobile/android/fenix/app/src/main/res/values-es-rES/strings.xml b/mobile/android/fenix/app/src/main/res/values-es-rES/strings.xml
index 5896187516..42ee948d2a 100644
--- a/mobile/android/fenix/app/src/main/res/values-es-rES/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-es-rES/strings.xml
@@ -51,12 +51,20 @@
- Guardado recientemente
+ Guardado recientemente
- Mostrar todos los marcadores guardados
+ Mostrar todos los marcadores guardados
- Eliminar
+ Eliminar
+
+
+
+ Marcadores
+
+ Mostrar todos los marcadores
+
+ Eliminar%1$s es producido por Mozilla.
@@ -194,6 +202,10 @@
ComplementosExtensiones
+
+ Gestionar extensiones
+
+ Descubrir más extensionesInformación de la cuenta
@@ -212,6 +224,8 @@
Abrir en una pestaña normalAgregar a la pantalla de Inicio
+
+ Añadir a la pantalla de inicio…Instalar
@@ -223,9 +237,13 @@
Traducir página
+ Guardar en colección…
+
Guardar en la colecciónCompartir
+
+ Compartir…Abrir en %1$s
@@ -280,6 +298,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Guardar
+
+ Añadir esta página a marcadores
+
+ Editar marcador
+
+ Guardar como PDF…
+
+ Activar vista de lectura
+
+ Desactivar vista de lectura
+
+ Traducir página…
+
+ Traducido al %1$s
+
+ Imprimir…
+
No hay extensiones aquí
@@ -377,8 +413,6 @@
Aviso de privacidad de Firefox
-
- Saber más en nuestro aviso de privacidadNos encanta mantenerte a salvoIdioma
- Traducción
+ Traducción
+
+ TraduccionesElección de datos
@@ -662,10 +698,6 @@
RequeridoOpcional
-
- Leer y cambiar los datos de sitios web
-
- Eliminar sitio webPermitir para todos los sitios
@@ -695,7 +727,9 @@
Volver a esta pestaña
- Marcadores recientes
+ Marcadores recientes
+
+ MarcadoresVisitados recientemente
@@ -789,8 +823,6 @@
HistorialMarcadores
-
- Inicios de sesiónContraseñas
@@ -817,8 +849,6 @@
and the third is the device model. -->
%1$s en %2$s %3$s
-
- Tarjetas de créditoMétodos de pago
@@ -836,6 +866,14 @@
Pestaña de %s
+
+
+ %1$s pestañas cerradas: %2$d
+
+ Ver pestañas cerradas recientemente
+
Excepciones
@@ -1786,13 +1824,9 @@
Puedes añadir fácilmente este sitio web a la pantalla de inicio de tu dispositivo para tener acceso instantáneo y navegar rápidamente, consiguiendo una experiencia similar a la de una aplicación real.
-
- Inicios de sesión y contraseñasContraseñas
- Guardar inicios de sesión y contraseñas
-
Guardar contraseñasPreguntar antes de guardar
@@ -1809,46 +1843,27 @@
Completar nombres de usuarios y contraseñas en otras aplicaciones de tu dispositivo.
-
- Añadir cuenta
-
Añadir contraseña
-
- Inicios de sesión sincronizadosSincronizar contraseñas
-
- Sincronizar inicios de sesión entre dispositivosSincronizar contraseñas entre dispositivos
-
- Inicios de sesión guardadosContraseñas guardadas
- Los inicios de sesión que guardes o sincronices con %s se mostrarán aquí.
-
Las contraseñas que guardes o sincronices con %s aparecerán aquí. Todas las contraseñas que guardes quedan cifradas.
-
- Saber más sobre Sync.Descubre más sobre SyncExcepciones
-
- Los inicios de sesión y contraseñas no guardados aparecerán aquí.%s no guardará contraseñas para los sitios que se listen aquí.
-
- No se guardarán los inicios de sesión y contraseñas para estos sitios.%s no guardará las contraseñas para estos sitios.Eliminar todas las excepciones
-
- Buscar inicios de sesiónBuscar contraseñas
@@ -1877,17 +1892,11 @@
Mostrar contraseñaOcultar contraseña
-
- Desbloquear para ver tus inicios de sesión guardadosDesbloquea para ver tus contraseñas guardadas
- Asegurar tus usuarios y contraseñas
-
Asegura tus contraseñas guardadas
- Configura un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus usuarios y contraseñas guardados si alguien más tiene tu dispositivo.
-
Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus contraseñas guardadas y evitar que sean accedidas por otras personas en caso de que alguien más tenga tu dispositivo.Más tarde
@@ -1906,9 +1915,6 @@
Usado por última vez
-
- Ordenar menú de inicio de sesión
-
Menú ordenar contraseñas
@@ -1917,16 +1923,10 @@
AutocompletadoDirecciones
-
- Tarjetas de créditoMétodos de pago
- Guardar y autocompletar tarjetas
-
Guardar y completar métodos de pago
-
- Los datos están cifrados%s cifra todos los métodos de pago que guardes
@@ -1934,25 +1934,17 @@
Sincronizar tarjetas entre dispositivosSincronizar tarjetas
-
- Añadir tarjeta de créditoAñadir tarjeta
-
- Administrar tarjetas guardadasAdministrar tarjetasAñadir direcciónAdministrar direcciones
-
- Guardar y autocompletar direccionesGuardar y completar direcciones
-
- Incluir información como números, correos electrónicos y direcciones de envíoIncluye números de teléfono y direcciones de correo electrónico
@@ -1976,8 +1968,6 @@
Eliminar tarjeta
- ¿Seguro que quieres eliminar esta tarjeta de crédito?
-
¿Eliminar tarjeta?Eliminar
@@ -1991,24 +1981,15 @@
Tarjetas guardadas
-
- Por favor, escriba un número válido de tarjeta de crédito
-
Introduce un número de tarjeta válido
-
- Por favor, rellena este campoAñadir un nombreDesbloquear para ver tus tarjetas guardadas
- Asegurar tus tarjetas de crédito
-
Protege tus métodos de pago guardados
- Configura un patrón de bloqueo, PIN o contraseña para proteger el acceso a tus tarjetas guardadas si alguien más accede a tu dispositivo.
-
Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus métodos de pago guardados y evitar que sean accedidos por otras personas en caso de que alguien más tenga tu dispositivo.Configurar ahora
@@ -2016,8 +1997,6 @@
Más tardeDesbloquear tu dispositivo
-
- Desbloquear para usar la información de la tarjeta de crédito almacenadaDesbloquea para utilizar métodos de pago guardados
@@ -2027,12 +2006,6 @@
Editar direcciónAdministrar direcciones
-
- Nombre
-
- Segundo nombre
-
- ApellidosNombre
@@ -2058,8 +2031,6 @@
Eliminar dirección
-
- ¿Seguro que quieres eliminar esta dirección?¿Eliminar esta dirección?
@@ -2159,49 +2130,29 @@
EliminarEditar
-
- ¿Seguro que quieres eliminar este inicio de sesión?¿Estás seguro de que quieres eliminar esta contraseña?EliminarCancelar
-
- Opciones de inicio de sesiónOpciones de contraseña
-
- El campo de texto editable para la dirección web del inicio de sesión.El campo de texto editable para la dirección del sitio web.
-
- El campo de texto editable para el nombre de usuario del inicio de sesión.El campo de texto editable para el nombre de usuario.
- El campo de texto editable para la contraseña del inicio de sesión.
-
El campo de texto editable para la contraseña.
-
- Guardar cambios para el inicio de sesión.Guardar cambios.
-
- EditarEditar contraseña
-
- Añadir nueva cuentaAñadir contraseña
-
- Se necesita contraseñaIntroduce una contraseña
- Se requiere nombre de usuario
-
Introduce un nombre de usuarioSe requiere nombre de servidor
@@ -2549,6 +2500,8 @@
Ahora noMostrar original
+
+ Se ha cargado la página original sin traducirHecho
@@ -2606,6 +2559,9 @@
Cerrar hoja de traducciones
+
+ Algunos ajustes no están disponibles temporalmente.
+
Traducciones
@@ -2628,6 +2584,9 @@
Selecciona un idioma para administrar las preferencias de ”traducir siempre“ y ”no traducir nunca“.
+
+ No se han podido cargar los idiomas. Inténtalo de nuevo más tarde.
+
Ofrecer traducción (predeterminado)
@@ -2651,6 +2610,8 @@
Eliminar %1$s
+
+ No se han podido cargar los sitios. Inténtalo de nuevo más tarde.¿Eliminar %1$s?
@@ -2728,13 +2689,18 @@
Ir a la página anterior
+
+ Abrir panel de depuración
+
Herramientas de pestañasNúmero de pestañas
- Activa
+ Activa
+
+ ActivoInactiva
@@ -2745,6 +2711,16 @@
Herramienta de creación de pestañasCantidad de pestañas a crear
+
+ El campo de texto está vacío
+
+ Introduce solo números enteros positivos
+
+ Introduce un número mayor que cero
+
+ Se ha superado el número máximo de pestañas (%1$s) que se pueden generar en una operaciónAñadir a pestañas activas
@@ -2761,11 +2737,11 @@
Aviso de privacidad
- Enviar
+ Enviar
- Cerrar
+ Cerrar
- ¡Gracias por tu opinión!
+ ¡Gracias por tu opinión!Muy satisfecho
@@ -2777,6 +2753,14 @@
Muy insatisfecho
+
+
+ Abrir la encuesta
+
+ Cerrar la encuesta
+
+ Cerrar
+
Inicios de sesión
diff --git a/mobile/android/fenix/app/src/main/res/values-es/strings.xml b/mobile/android/fenix/app/src/main/res/values-es/strings.xml
index 5896187516..42ee948d2a 100644
--- a/mobile/android/fenix/app/src/main/res/values-es/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-es/strings.xml
@@ -51,12 +51,20 @@
- Guardado recientemente
+ Guardado recientemente
- Mostrar todos los marcadores guardados
+ Mostrar todos los marcadores guardados
- Eliminar
+ Eliminar
+
+
+
+ Marcadores
+
+ Mostrar todos los marcadores
+
+ Eliminar%1$s es producido por Mozilla.
@@ -194,6 +202,10 @@
ComplementosExtensiones
+
+ Gestionar extensiones
+
+ Descubrir más extensionesInformación de la cuenta
@@ -212,6 +224,8 @@
Abrir en una pestaña normalAgregar a la pantalla de Inicio
+
+ Añadir a la pantalla de inicio…Instalar
@@ -223,9 +237,13 @@
Traducir página
+ Guardar en colección…
+
Guardar en la colecciónCompartir
+
+ Compartir…Abrir en %1$s
@@ -280,6 +298,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Guardar
+
+ Añadir esta página a marcadores
+
+ Editar marcador
+
+ Guardar como PDF…
+
+ Activar vista de lectura
+
+ Desactivar vista de lectura
+
+ Traducir página…
+
+ Traducido al %1$s
+
+ Imprimir…
+
No hay extensiones aquí
@@ -377,8 +413,6 @@
Aviso de privacidad de Firefox
-
- Saber más en nuestro aviso de privacidadNos encanta mantenerte a salvoIdioma
- Traducción
+ Traducción
+
+ TraduccionesElección de datos
@@ -662,10 +698,6 @@
RequeridoOpcional
-
- Leer y cambiar los datos de sitios web
-
- Eliminar sitio webPermitir para todos los sitios
@@ -695,7 +727,9 @@
Volver a esta pestaña
- Marcadores recientes
+ Marcadores recientes
+
+ MarcadoresVisitados recientemente
@@ -789,8 +823,6 @@
HistorialMarcadores
-
- Inicios de sesiónContraseñas
@@ -817,8 +849,6 @@
and the third is the device model. -->
%1$s en %2$s %3$s
-
- Tarjetas de créditoMétodos de pago
@@ -836,6 +866,14 @@
Pestaña de %s
+
+
+ %1$s pestañas cerradas: %2$d
+
+ Ver pestañas cerradas recientemente
+
Excepciones
@@ -1786,13 +1824,9 @@
Puedes añadir fácilmente este sitio web a la pantalla de inicio de tu dispositivo para tener acceso instantáneo y navegar rápidamente, consiguiendo una experiencia similar a la de una aplicación real.
-
- Inicios de sesión y contraseñasContraseñas
- Guardar inicios de sesión y contraseñas
-
Guardar contraseñasPreguntar antes de guardar
@@ -1809,46 +1843,27 @@
Completar nombres de usuarios y contraseñas en otras aplicaciones de tu dispositivo.
-
- Añadir cuenta
-
Añadir contraseña
-
- Inicios de sesión sincronizadosSincronizar contraseñas
-
- Sincronizar inicios de sesión entre dispositivosSincronizar contraseñas entre dispositivos
-
- Inicios de sesión guardadosContraseñas guardadas
- Los inicios de sesión que guardes o sincronices con %s se mostrarán aquí.
-
Las contraseñas que guardes o sincronices con %s aparecerán aquí. Todas las contraseñas que guardes quedan cifradas.
-
- Saber más sobre Sync.Descubre más sobre SyncExcepciones
-
- Los inicios de sesión y contraseñas no guardados aparecerán aquí.%s no guardará contraseñas para los sitios que se listen aquí.
-
- No se guardarán los inicios de sesión y contraseñas para estos sitios.%s no guardará las contraseñas para estos sitios.Eliminar todas las excepciones
-
- Buscar inicios de sesiónBuscar contraseñas
@@ -1877,17 +1892,11 @@
Mostrar contraseñaOcultar contraseña
-
- Desbloquear para ver tus inicios de sesión guardadosDesbloquea para ver tus contraseñas guardadas
- Asegurar tus usuarios y contraseñas
-
Asegura tus contraseñas guardadas
- Configura un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus usuarios y contraseñas guardados si alguien más tiene tu dispositivo.
-
Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus contraseñas guardadas y evitar que sean accedidas por otras personas en caso de que alguien más tenga tu dispositivo.Más tarde
@@ -1906,9 +1915,6 @@
Usado por última vez
-
- Ordenar menú de inicio de sesión
-
Menú ordenar contraseñas
@@ -1917,16 +1923,10 @@
AutocompletadoDirecciones
-
- Tarjetas de créditoMétodos de pago
- Guardar y autocompletar tarjetas
-
Guardar y completar métodos de pago
-
- Los datos están cifrados%s cifra todos los métodos de pago que guardes
@@ -1934,25 +1934,17 @@
Sincronizar tarjetas entre dispositivosSincronizar tarjetas
-
- Añadir tarjeta de créditoAñadir tarjeta
-
- Administrar tarjetas guardadasAdministrar tarjetasAñadir direcciónAdministrar direcciones
-
- Guardar y autocompletar direccionesGuardar y completar direcciones
-
- Incluir información como números, correos electrónicos y direcciones de envíoIncluye números de teléfono y direcciones de correo electrónico
@@ -1976,8 +1968,6 @@
Eliminar tarjeta
- ¿Seguro que quieres eliminar esta tarjeta de crédito?
-
¿Eliminar tarjeta?Eliminar
@@ -1991,24 +1981,15 @@
Tarjetas guardadas
-
- Por favor, escriba un número válido de tarjeta de crédito
-
Introduce un número de tarjeta válido
-
- Por favor, rellena este campoAñadir un nombreDesbloquear para ver tus tarjetas guardadas
- Asegurar tus tarjetas de crédito
-
Protege tus métodos de pago guardados
- Configura un patrón de bloqueo, PIN o contraseña para proteger el acceso a tus tarjetas guardadas si alguien más accede a tu dispositivo.
-
Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus métodos de pago guardados y evitar que sean accedidos por otras personas en caso de que alguien más tenga tu dispositivo.Configurar ahora
@@ -2016,8 +1997,6 @@
Más tardeDesbloquear tu dispositivo
-
- Desbloquear para usar la información de la tarjeta de crédito almacenadaDesbloquea para utilizar métodos de pago guardados
@@ -2027,12 +2006,6 @@
Editar direcciónAdministrar direcciones
-
- Nombre
-
- Segundo nombre
-
- ApellidosNombre
@@ -2058,8 +2031,6 @@
Eliminar dirección
-
- ¿Seguro que quieres eliminar esta dirección?¿Eliminar esta dirección?
@@ -2159,49 +2130,29 @@
EliminarEditar
-
- ¿Seguro que quieres eliminar este inicio de sesión?¿Estás seguro de que quieres eliminar esta contraseña?EliminarCancelar
-
- Opciones de inicio de sesiónOpciones de contraseña
-
- El campo de texto editable para la dirección web del inicio de sesión.El campo de texto editable para la dirección del sitio web.
-
- El campo de texto editable para el nombre de usuario del inicio de sesión.El campo de texto editable para el nombre de usuario.
- El campo de texto editable para la contraseña del inicio de sesión.
-
El campo de texto editable para la contraseña.
-
- Guardar cambios para el inicio de sesión.Guardar cambios.
-
- EditarEditar contraseña
-
- Añadir nueva cuentaAñadir contraseña
-
- Se necesita contraseñaIntroduce una contraseña
- Se requiere nombre de usuario
-
Introduce un nombre de usuarioSe requiere nombre de servidor
@@ -2549,6 +2500,8 @@
Ahora noMostrar original
+
+ Se ha cargado la página original sin traducirHecho
@@ -2606,6 +2559,9 @@
Cerrar hoja de traducciones
+
+ Algunos ajustes no están disponibles temporalmente.
+
Traducciones
@@ -2628,6 +2584,9 @@
Selecciona un idioma para administrar las preferencias de ”traducir siempre“ y ”no traducir nunca“.
+
+ No se han podido cargar los idiomas. Inténtalo de nuevo más tarde.
+
Ofrecer traducción (predeterminado)
@@ -2651,6 +2610,8 @@
Eliminar %1$s
+
+ No se han podido cargar los sitios. Inténtalo de nuevo más tarde.¿Eliminar %1$s?
@@ -2728,13 +2689,18 @@
Ir a la página anterior
+
+ Abrir panel de depuración
+
Herramientas de pestañasNúmero de pestañas
- Activa
+ Activa
+
+ ActivoInactiva
@@ -2745,6 +2711,16 @@
Herramienta de creación de pestañasCantidad de pestañas a crear
+
+ El campo de texto está vacío
+
+ Introduce solo números enteros positivos
+
+ Introduce un número mayor que cero
+
+ Se ha superado el número máximo de pestañas (%1$s) que se pueden generar en una operaciónAñadir a pestañas activas
@@ -2761,11 +2737,11 @@
Aviso de privacidad
- Enviar
+ Enviar
- Cerrar
+ Cerrar
- ¡Gracias por tu opinión!
+ ¡Gracias por tu opinión!Muy satisfecho
@@ -2777,6 +2753,14 @@
Muy insatisfecho
+
+
+ Abrir la encuesta
+
+ Cerrar la encuesta
+
+ Cerrar
+
Inicios de sesión
diff --git a/mobile/android/fenix/app/src/main/res/values-eu/strings.xml b/mobile/android/fenix/app/src/main/res/values-eu/strings.xml
index cd905135c3..80955bc9b8 100644
--- a/mobile/android/fenix/app/src/main/res/values-eu/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-eu/strings.xml
@@ -49,12 +49,20 @@
- Gordetako azkenak
+ Gordetako azkenak
- Erakutsi gordetako laster-marka guztiak
+ Erakutsi gordetako laster-marka guztiak
- Kendu
+ Kendu
+
+
+
+ Laster-markak
+
+ Erakutsi laster-marka guztiak
+
+ Kendu%1$s Mozillak egina da.
@@ -144,8 +152,10 @@
Fitxa pribatu berria
-
- Pasahitzen lasterbidea
+
+ Pasahitzak
+
+ Pasahitzen lasterbidea
@@ -186,11 +196,17 @@
Gelditu
- Gehigarriak
+ Gehigarriak
+
+ Hedapenak
+
+ Kudeatu hedapenak
+
+ Deskubritu hedapen gehiagoKontuaren informazioa
- Gehigarririk ez hemen
+ Gehigarririk ez hemenLaguntza
@@ -205,19 +221,27 @@
Ireki fitxa arrunteanGehitu hasierako pantailan
+
+ Gehitu hasierako pantailan…
- Instalatu
+ InstalatuSinkronizatu berriroBilatu orrian
+
+ Bilatu orrian…Itzuli orria
+ Gorde bilduman…
+
Gorde bildumanPartekatu
+
+ Partekatu…Ireki %1$s nabigatzailean
@@ -246,6 +270,51 @@
Pertsonalizatu hasiera-orria
+
+ Hasi saioa
+
+
+ Sinkronizatu pasahitzak, fitxak eta gehiago
+
+ Hasi berriro saioa sinkronizatzeko
+
+ Sinkronizazioa pausatuta
+
+ Fitxa pribatu berria
+
+ Pasahitzak
+
+ Berria %1$s(e)n
+
+ Aldatu mahaigaineko gunera
+
+ Tresnak
+
+ Gorde
+
+ Egin orriaren laster-marka
+
+ Editatu laster-marka
+
+ Gorde PDF gisa…
+
+ Aktibatu irakurtzeko ikuspegia
+
+ Desaktibatu irakurtzeko ikuspegia
+
+ Itzuli orria…
+
+ %1$s hizkuntzara itzulita
+
+ Inprimatu…
+
+
+
+ Hedapenik ez hemen
+
Hasiera-pantaila
@@ -551,6 +620,10 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.Birkonektatu sinkronizatzeari berrekitekoHizkuntza
+
+ Itzulpena
+
+ ItzulpenakDatu-aukerak
@@ -603,10 +676,14 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.Aplikaziotik irteten aldaketak aplikatzeko…
- Gehigarriak
+ Gehigarriak
+
+ Hedapenak
- Instalatu gehigarria fitxategitik
+ Instalatu gehigarria fitxategitik
+
+ Instalatu hedapena fitxategitikJakinarazpenak
@@ -615,9 +692,25 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.Ez dago baimenduta
+
+
+ Beharrezkoa
+
+ Aukerakoa
+
+ Webguneetako datuak irakurri eta aldatzea
+
+ Ezabatu webgunea
+
+ Baimendu gune guztietarako
+
+ Hedapena fidagarritzat baduzu, webgune guztietarako baimena eman diezaiokezu.
+
- Gehigarrien bilduma pertsonalizatua
+ Gehigarrien bilduma pertsonalizatua
+
+ Hedapenen bilduma pertsonalizatuaAdos
@@ -627,13 +720,18 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.Bildumaren jabea (erabiltzaile-IDa)
- Gehigarrien bilduma aldatu egin da. Aplikaziotik irteten aldaketak aplikatzeko…
+ Gehigarrien bilduma aldatu egin da. Aplikaziotik irteten aldaketak aplikatzeko…
+
+
+ Hedapenen bilduma aldatu egin da. Aplikaziotik irteten aldaketak aplikatzeko…Itzuli zeudenera
- Azken laster-markak
+ Azken laster-markak
+
+ Laster-markakBisitatutako azkenak
@@ -682,21 +780,37 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
- Gehigarri berriak erabilgarri orain
+ Gehigarri berriak erabilgarri orain
+
+ Hedapen berriak erabilgarri orainEman begiratua Firefox zure egiten lagunduko dizuten 100 gehigarri berri baino gehiagori.
- Esploratu gehigarriak
+ Esploratu gehigarriak
-
+
+ Arakatu hedapenak
+
+
- Gehigarriak aldi baterako desgaitu dira
+ Gehigarriak aldi baterako desgaitu dira
+
+ Hedapenak aldi baterako desgaitu dira
- Gehigarri bat edo gehiago ez dabil eta zure sistema desegonkortzen ari da. %1$s saiatu da gehigarriak berrabiarazten, arrakastarik gabe.\n\nEz da gehigarririk berrabiaraziko zure uneko saioan.\n\nGeghiarriak kendu edo desgaitzeak arazoa konpon lezake.
+ Gehigarri bat edo gehiago ez dabil eta zure sistema desegonkortzen ari da. %1$s saiatu da gehigarriak berrabiarazten, arrakastarik gabe.\n\nEz da gehigarririk berrabiaraziko zure uneko saioan.\n\nGeghiarriak kendu edo desgaitzeak arazoa konpon lezake.
+
+ Hedapen bat edo gehiago ez dabil eta zure sistema desegonkortzen ari da. %1$s saiatu da hedapena(k) berrabiarazten, arrakastarik gabe.\n\nEz da hedapenik berrabiaraziko zure uneko saioan.\n\nHedapenak kendu edo desgaitzeak arazoa konpon lezake.
- Probatu gehigarriak berrabiarazten
+ Probatu gehigarriak berrabiarazten
+
+ Saiatu hedapenak berrabiarazten
- Jarraitu gehigarriak desgaituta
+ Jarraitu gehigarriak desgaituta
+
+
+ Jarraitu hedapenak desgaituta
@@ -757,6 +871,14 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.%s gailuko fitxa
+
+
+ %1$s fitxa itxita: %2$d
+
+ Ikusi itxitako azken fitxak
+
Salbuespenak
@@ -2443,10 +2565,14 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.Itzuli hemendikItzuli hona
+
+ Probatu beste iturburu-hizkuntza batUne honetan ezErakutsi jatorrizkoa
+
+ Jatorrizko itzuli gabeko orria kargatutaEginda
@@ -2467,7 +2593,7 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Barkatu, %1$s ez dugu onartzen oraindik.
- Argibide gehiago
+ Argibide gehiagoItzultzen…
@@ -2481,7 +2607,9 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
- Itzulpenen aukerak
+ Itzulpenen aukerak
+
+ Itzulpenen aukerakEskaini beti itzultzea
@@ -2500,6 +2628,9 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
%1$s(e)ko itzulpenei buruz
+
+ Itxi itzulpenen orria
+
Itzulpenak
@@ -2604,6 +2735,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Deskargatu datuak aurrezteko moduan egotean (%1$s)?Hizkuntzak erdizka deskargatzen ditugu zure cachera itzulpenak pribatu manten daitezen.
+
+ Hizkuntzak erdizka deskargatzen ditugu itzulpenak pribatu manten daitezen.Deskargatu beti datuak aurrezteko moduan
@@ -2618,12 +2751,19 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Arazketa-tresnakNabigatu atzera
+
+
+ Ireki arazketarako menu lerrakorra
+
+
Fitxen tresnakFitxa kopurua
- Aktibo
+ Aktibo
+
+ AktiboInaktibo
@@ -2640,4 +2780,39 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gehitu fitxa inaktiboetaraGehitu fitxa pribatuetara
+
+
+
+
+ Jarraitu
+
+ Burutu inkesta
+
+ Pribatutasun-oharra
+
+ Bidali
+
+ Itxi
+
+ Eskerrik asko zure iritziagatik!
+
+ Oso kontent
+
+ Kontent
+
+ Neutrala
+
+ Kontentagaitz
+
+ Oso kontentagaitz
+
+
+
+ Saio-hasierak
+
+ Uneko domeinua: %s
+
+ Gehitu saio-hasiera faltsua domeinu honetarako
+
+ Ezabatu %s erabiltzaile-izena duen saio-hasiera
diff --git a/mobile/android/fenix/app/src/main/res/values-fi/strings.xml b/mobile/android/fenix/app/src/main/res/values-fi/strings.xml
index aa7be14543..004d8494cd 100644
--- a/mobile/android/fenix/app/src/main/res/values-fi/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-fi/strings.xml
@@ -201,6 +201,10 @@
LisäosatLaajennukset
+
+ Hallitse laajennuksia
+
+ Löydä lisää laajennuksiaTilin tiedot
@@ -219,6 +223,8 @@
Avaa tavallisessa välilehdessäLisää aloitusnäytölle
+
+ Lisää aloitusnäytölle…Asenna
@@ -230,10 +236,14 @@
Käännä sivu
+ Tallenna kokoelmaan…
+
Tallenna kokoelmaanJaa
+
+ Jaa…Avaa sovelluksessa %1$s
@@ -288,6 +298,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Tallenna
+
+ Lisää tämä sivu kirjanmerkkeihin
+
+ Muokkaa kirjanmerkkiä
+
+ Tallenna PDF-muodossa…
+
+ Avaa lukunäkymä
+
+ Sulje lukunäkymä
+
+ Käännä sivu…
+
+ Käännetty kielelle %1$s
+
+ Tulosta…
+
Täällä ei ole laajennuksia
@@ -385,8 +413,6 @@
Firefoxin tietosuojakäytäntö
-
- Lue lisää tietosuojakäytännöstämmeTurvaamisesi on tärkeää meilleKieli
- Käännös
+ Käännös
+
+ KäännöksetTietovalinnat
@@ -670,10 +698,6 @@
PakollinenValinnainen
-
- Lue ja muuta verkkosivuston dataa
-
- Poista verkkosivustoSalli kaikille sivustoille
@@ -799,8 +823,6 @@
HistoriaKirjanmerkit
-
- KirjautumistiedotSalasanat
@@ -827,8 +849,6 @@
and the third is the device model. -->
%1$s laitteella %2$s %3$s
-
- LuottokortitMaksutavat
@@ -844,6 +864,14 @@
Välilehti laitteesta %s
+
+
+ %1$s-välilehtiä suljettu: %2$d
+
+ Näytä viimeksi suljetut välilehdet
+
Poikkeukset
@@ -1782,13 +1810,9 @@
Voit lisätä tämän sivuston laitteesi aloitusnäytölle, jolloin sivuston käyttö onnistuu nopeasti ja tarjoaa sovelluksen kaltaisen kokemuksen.
-
- Käyttäjätunnukset ja salasanatSalasanat
- Tallenna käyttäjätunnukset ja salasanat
-
Tallenna salasanatKysy tallennusta
@@ -1804,46 +1828,27 @@
Täytä käyttäjätunnukset ja salasanat muissa laitteesi sovelluksissa.
-
- Lisää kirjautumistieto
-
Lisää salasana
-
- Synkronoi kirjautumistiedotSynkronoi salasanat
-
- Synkronoi kirjautumistiedot laitteiden välilläSynkronoi salasanat eri laitteiden välillä
-
- Tallennetut kirjautumistiedotTallennetut salasanat
- %siin tallentamasi tai synkronoimasi kirjautumistiedot näkyvät täällä.
-
%siin tallentamasi tai synkronoimasi salasanat näkyvät tässä. Kaikki tallentamasi salasanat ovat salattuja.
-
- Lue lisää Syncista.Lisätietoja synkronoinnistaPoikkeukset
-
- Käyttäjätunnukset ja salanat, joita ei tallenneta, näytetään täällä.%s ei tallenna tässä lueteltujen sivustojen salasanoja.
-
- Käyttäjätunnuksia ja salasanoja ei tallenneta näille sivustoille.%s ei tallenna näiden sivustojen salasanoja.Poista kaikki poikkeukset
-
- Etsi kirjautumistiedoistaEtsi salasanoja
@@ -1872,17 +1877,11 @@
Näytä salasanaPiilota salasana
-
- Avaa lukitus nähdäksesi tallennetut kirjautumistiedotAvaa lukitus nähdäksesi tallennetut salasanat
- Suojaa käyttäjätunnuksesi ja salasanasi
-
Suojaa tallennetut salasanat
- Aseta laitteen avaukseen tarkoitettu kuvio, PIN-koodi tai salasana suojataksesi tallennetut kirjautumistiedot ja salasanat siltä varalta, että joku saa laitteesi haltuunsa.
-
Määritä laitteen lukituskuvio, PIN-koodi tai salasana suojataksesi tallennettuja salasanojasi, jos laitteesi on jollain toisella.Myöhemmin
@@ -1900,8 +1899,6 @@
Nimi (A-Ö)Viimeksi käytetty
-
- Järjestä kirjautumistietojen valikkoSalasanojen järjestysvalikko
@@ -1911,41 +1908,27 @@
Automaattinen täyttöOsoitteet
-
- LuottokortitMaksutavat
- Tallenna ja täytä kortit automaattisesti
-
Tallenna ja täytä maksutavat
-
- Tiedot on salattu%s salaa kaikki tallentamasi maksutavatSynkronoi kortit laitteiden välilläSynkronoi kortit
-
- Lisää luottokorttiLisää kortti
-
- Hallinnoi tallennettuja korttejaHallitse korttejaLisää osoiteHallitse osoitteita
-
- Tallenna ja täytä osoitteet automaattisestiTallenna ja täytä osoitteet
-
- Sisällytä tiedot kuten numerot, sähköpostiosoitteet ja toimitusosoitteetSisältää puhelinnumerot ja sähköpostiosoitteet
@@ -1969,8 +1952,6 @@
Poista kortti
- Haluatko varmasti poistaa tämän luottokortin?
-
Poistetaanko kortti?Poista
@@ -1984,24 +1965,15 @@
Tallennetut kortit
-
- Kirjoita kelvollinen luottokortin numero
-
Anna kelvollinen kortin numero
-
- Täytä tämä kenttäLisää nimiAvaa lukitus nähdäksesi tallennetut kortit
- Suojaa luottokorttisi
-
Suojaa tallennetut maksutavat
- Aseta laitteen avaukseen tarkoitettu kuvio, PIN-koodi tai salasana suojataksesi tallennetut luottokorttitiedot siltä varalta, että joku saa laitteesi haltuunsa.
-
Määritä laitteen lukituskuvio, PIN-koodi tai salasana suojataksesi tallennettuja maksutapojasi, jos laitteesi on jollain toisella.Aseta nyt
@@ -2010,9 +1982,6 @@
Avaa laitteen lukitus
-
- Avaa lukitus käyttääksesi tallennettuja luottokorttitietoja
-
Avaa lukitus käyttääksesi tallennettuja maksutapoja
@@ -2021,12 +1990,6 @@
Muokkaa osoitettaHallitse osoitteita
-
- Etunimi
-
- Toinen nimi
-
- SukunimiNimi
@@ -2052,8 +2015,6 @@
Poista osoite
-
- Haluatko varmasti poistaa tämän osoitteen?Poistetaanko tämä osoite?
@@ -2153,49 +2114,29 @@
PoistaMuokkaa
-
- Haluatko varmasti poistaa tämän kirjautumistiedon?Haluatko varmasti poistaa tämän salasanan?PoistaPeruuta
-
- Kirjautumistietojen valinnatSalasanojen asetukset
-
- Muokattava tekstikenttä kirjautumisen verkkosivua varten.Verkkosivuston muokattava tekstikenttä.
-
- Muokattava tekstikenttä kirjautumisen käyttäjätunnusta varten.Käyttäjätunnuksen muokattava tekstikenttä.
- Muokattava tekstikenttä kirjautumisen salasanaa varten.
-
Salasanan muokattava tekstikenttä.
-
- Tallenna muutokset kirjautumistietoihin.Tallenna muutokset.
-
- MuokkaaMuokkaa salasanaa
-
- Lisää uusi kirjautumistietoLisää salasana
-
- Salasana vaaditaanKirjoita salasana
- Käyttäjätunnus vaaditaan
-
Kirjoita käyttäjätunnusIsäntänimi vaaditaan
@@ -2582,6 +2523,11 @@
Tietoja käännöksistä %1$sissa
+
+ Sulje käännössivu
+
+ Jotkut asetukset eivät ole tilapäisesti käytettävissä.
+
Käännökset
@@ -2606,6 +2552,9 @@
Valitse kieli hallitaksesi "käännä aina"- ja "älä käännä koskaan"-asetuksia.
+
+ Kieliä ei voitu ladata. Tarkista myöhemmin uudelleen.
+
Tarjoa käännöstä (oletus)
@@ -2629,6 +2578,8 @@
Poista %1$s
+
+ Sivustoja ei voitu ladata. Tarkista myöhemmin uudelleen.Poistetaanko %1$s?
@@ -2706,13 +2657,18 @@
Siirry taaksepäin
+
+ Avaa vianjäljitysvalikko
+
VälilehtityökalutVälilehtien määrä
- Aktiivinen
+ Aktiivinen
+
+ AktiivinenPassiivinen
@@ -2723,6 +2679,16 @@
Välilehtien luontityökaluLuotavien välilehtien määrä
+
+ Tekstikenttä on tyhjä
+
+ Anna vain positiivisia kokonaislukuja
+
+ Anna numero, joka on suurempi kuin nolla
+
+ Yhdellä toiminnolla luotavien välilehtien enimmäismäärä (%1$s) täynnäLisää aktiivisiin välilehtiin
@@ -2739,11 +2705,11 @@
Tietosuojakäytäntö
- Lähetä
+ Lähetä
- Sulje
+ Sulje
- Kiitos palautteestasi!
+ Kiitos palautteestasi!Hyvin tyytyväinen
@@ -2755,6 +2721,14 @@
Hyvin tyytymätön
+
+
+ Avaa kysely
+
+ Sulje kysely
+
+ Sulje
+
Kirjautumistiedot
diff --git a/mobile/android/fenix/app/src/main/res/values-fr/strings.xml b/mobile/android/fenix/app/src/main/res/values-fr/strings.xml
index 59aafe7a2d..d39900ddce 100644
--- a/mobile/android/fenix/app/src/main/res/values-fr/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-fr/strings.xml
@@ -202,6 +202,10 @@
Modules complémentairesExtensions
+
+ Gérer les extensions
+
+ Découvrir d’autres extensionsInformations du compte
@@ -220,6 +224,8 @@
Ouvrir dans un onglet classiqueAjouter à l’écran d’accueil
+
+ Ajouter à l’écran d’accueil…Installer
@@ -231,9 +237,13 @@
Traduire la page
+ Enregistrer dans une collection…
+
Enregistrer dans une collectionPartager
+
+ Partager…Ouvrir avec %1$s
@@ -288,6 +298,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Enregistrer
+
+ Marquer cette page
+
+ Modifier le marque-page
+
+ Enregistrer en PDF…
+
+ Passer en mode lecture
+
+ Quitter le mode lecture
+
+ Traduire la page…
+
+ Traduit en %1$s
+
+ Imprimer…
+
Aucune extension disponible
@@ -385,8 +413,6 @@
Politique de confidentialité de Firefox
-
- En savoir plus dans notre politique de confidentialitéVotre protection compte pour nousLangues
- Traduction
+ Traduction
+
+ TraductionsChoix de données
@@ -670,10 +698,6 @@
ObligatoireFacultatif
-
- Consulter et modifier les données de sites web
-
- Supprimer le site webAutoriser pour tous les sites
@@ -799,8 +823,6 @@
HistoriqueMarque-pages
-
- IdentifiantsMots de passe
@@ -827,8 +849,6 @@
and the third is the device model. -->
%1$s sur %2$s %3$s
-
- Cartes bancairesMoyens de paiement
@@ -846,6 +866,14 @@
Onglet provenant de %s
+
+
+ %2$d onglets fermés sur %1$s
+
+ Afficher les onglets récemment fermés
+
Exceptions
@@ -1797,13 +1825,9 @@
Vous pouvez facilement ajouter ce site à l’écran d’accueil de votre appareil pour y avoir accès directement et naviguer plus rapidement, comme si vous utilisiez une application.
-
- Identifiants et mots de passeMots de passe
- Enregistrer les identifiants et les mots de passe
-
Enregistrer les mots de passeDemander pour enregistrer
@@ -1819,46 +1843,27 @@
Remplit les noms d’utilisateur et les mots de passe dans d’autres applications sur votre appareil.
-
- Ajouter un identifiant
-
Ajouter un mot de passe
-
- Synchroniser les identifiantsSynchroniser les mots de passe
-
- Synchroniser les identifiants entre vos appareilsSynchronisez les mots de passe entre vos appareils
-
- Identifiants enregistrésMots de passe enregistrés
- Les identifiants que vous enregistrez ou synchronisez avec %s s’afficheront ici.
-
Les mots de passe que vous enregistrez ou synchronisez avec %s seront répertoriés ici. Tous les mots de passe que vous enregistrez sont chiffrés.
-
- En savoir plus sur Sync.En savoir plus sur la synchronisationExceptions
-
- Les identifiants et les mots de passe qui ne sont pas enregistrés seront affichés ici.%s n’enregistrera pas les mots de passe pour les sites listés ici.
-
- Les identifiants et les mots de passe ne seront pas enregistrés pour ces sites.%s n’enregistrera pas les mots de passe pour ces sites.Supprimer toutes les exceptions
-
- Rechercher des identifiantsRechercher des mots de passe
@@ -1887,17 +1892,11 @@
Afficher le mot de passeMasquer le mot de passe
-
- Déverrouillez pour afficher vos identifiants enregistrésDéverrouillez pour afficher vos mots de passe enregistrés
- Protégez vos identifiants et mots de passe
-
Sécurisez les mots de passe enregistrés
- Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos identifiants de connexion et mots de passe enregistrés pour le cas où quelqu’un accède à votre appareil.
-
Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos mots de passe enregistrés si jamais quelqu’un accède à votre appareil.Plus tard
@@ -1914,8 +1913,6 @@
Nom (A-Z)Dernière utilisation
-
- Menu de tri des identifiantsMenu de tri des mots de passe
@@ -1925,41 +1922,27 @@
Remplissage automatiqueAdresses
-
- Cartes bancairesMoyens de paiement
- Enregistrer et remplir automatiquement les cartes
-
Enregistrer et renseigner les moyens de paiement
-
- Les données sont chiffrées%s chiffre tous les moyens de paiement que vous enregistrezSynchroniser les cartes entre vos appareilsSynchroniser les cartes
-
- Ajouter une carte bancaireAjouter une carte
-
- Gérer les cartes enregistréesGérer les cartesAjouter une adresseGérer les adresses
-
- Enregistrer et remplir automatiquement les adressesEnregistrer et remplir automatiquement les adresses
-
- Cela comprend des informations telles que des numéros, des adresses e-mail et des adresses d’expéditionY compris les numéros de téléphone et les adresses e-mail
@@ -1983,8 +1966,6 @@
Supprimer la carte
- Voulez-vous vraiment supprimer cette carte bancaire ?
-
Supprimer la carte ?Supprimer
@@ -1998,24 +1979,15 @@
Cartes enregistrées
-
- Veuillez saisir un numéro de carte bancaire valide
-
Saisissez un numéro de carte valide
-
- Veuillez compléter ce champAjouter un nomDéverrouillez pour afficher vos cartes enregistrées
- Protégez vos cartes bancaires
-
Sécurisez vos moyens de paiement enregistrés
- Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos cartes bancaires enregistrées si jamais quelqu’un accède à votre appareil.
-
Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos moyens de paiement enregistrés si jamais quelqu’un accède à votre appareil.Configurer maintenant
@@ -2023,8 +1995,6 @@
Plus tardDéverrouillez votre appareil
-
- Déverrouillez pour utiliser les informations de cartes bancaires enregistréesDéverrouillez pour utiliser des moyens de paiement enregistrés
@@ -2034,12 +2004,6 @@
Modifier l’adresseGérer les adresses
-
- Prénom
-
- Deuxième prénom
-
- Nom de familleNom complet
@@ -2065,8 +2029,6 @@
Supprimer l’adresse
-
- Voulez-vous vraiment supprimer cette adresse ?Supprimer cette adresse ?
@@ -2165,49 +2127,29 @@
SupprimerModifier
-
- Voulez-vous vraiment supprimer cet identifiant ?Voulez-vous vraiment supprimer ce mot de passe ?SupprimerAnnuler
-
- Options de l’identifiantOptions de mot de passe
-
- Le champ de texte modifiable pour l’adresse web de l’identifiant.Le champ de texte modifiable pour l’adresse du site web.
-
- Le champ de texte modifiable pour le nom d’utilisateur de l’identifiant.Le champ de texte modifiable pour le nom d’utilisateur.
- Le champ de texte modifiable pour le mot de passe de l’identifiant.
-
Le champ de texte modifiable pour le mot de passe.
-
- Enregistrez les modifications de l’identifiant.Enregistrer les modifications.
-
- ModifierModifier le mot de passe
-
- Ajouter un nouvel identifiantAjouter un mot de passe
-
- Mot de passe requisSaisissez un mot de passe
- Le nom d’utilisateur doit être renseigné.
-
Saisissez un nom d’utilisateurLe nom d’hôte est requis
@@ -2617,6 +2559,9 @@
Fermer l’onglet Traductions
+
+ Certains paramètres sont temporairement indisponibles.
+
Traductions
@@ -2640,6 +2585,9 @@
Sélectionnez une langue pour gérer les préférences « Toujours traduire » et « Ne jamais traduire ».
+
+ Impossible de charger les langues. Veuillez réessayer plus tard.
+
Proposer de traduire (par défaut)
@@ -2662,6 +2610,8 @@
Supprimer %1$s
+
+ Impossible de charger des sites. Veuillez réessayer plus tard.Supprimer %1$s ?
@@ -2739,13 +2689,18 @@
Revenir
+
+ Ouvrir le panneau de débogage
+
Outils d’ongletsNombre d’onglets
- Actifs
+ Actifs
+
+ ActifInactifs
@@ -2756,6 +2711,16 @@
Outil de création d’ongletsNombre d’onglets à créer
+
+ Le champ de texte est vide
+
+ Saisissez uniquement des nombres entiers positifs
+
+ Saisissez un nombre supérieur à zéro
+
+ Vous avez dépassé le nombre maximal d’onglets (%1$s) qui peuvent être générés en une seule opérationAjouter aux onglets actifs
@@ -2772,11 +2737,11 @@
Politique de confidentialité
- Envoyer
+ Envoyer
- Fermer
+ Fermer
- Merci de votre retour !
+ Merci de votre retour !Très satisfait·e
@@ -2788,6 +2753,14 @@
Très insatisfait·e
+
+
+ Ouvrir le sondage
+
+ Fermer le sondage
+
+ Fermer
+
Identifiants
diff --git a/mobile/android/fenix/app/src/main/res/values-fur/strings.xml b/mobile/android/fenix/app/src/main/res/values-fur/strings.xml
index 8f59de5cbf..20676406c0 100644
--- a/mobile/android/fenix/app/src/main/res/values-fur/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-fur/strings.xml
@@ -199,6 +199,10 @@
Components adizionâiEstensions
+
+ Gjestìs estensions
+
+ Scuvierç altris estensionsInformazions account
@@ -217,6 +221,8 @@
Vierç intune schede normâlZonte a schermade principâl
+
+ Zonte a scherm. di inizi…Instale
@@ -228,9 +234,13 @@
Tradûs pagjine
+ Salve intune racuelte…
+
Salve intune racuelteCondivît
+
+ Condivît…Vierç in %1$s
@@ -283,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Salve
+
+ Zonte pagjine ai segnelibris
+
+ Modifiche segnelibri
+
+ Salve come PDF…
+
+ Ative Viodude di leture
+
+ Disative Viodude di leture
+
+ Tradûs pagjine…
+
+ Voltade par %1$s
+
+ Stampe…
+
Nissune estension achì
@@ -377,8 +405,6 @@
Informative su la riservatece di Firefox
-
- Plui informazions te nestre informative su la riservateceNus plâs tignîti di cont
- Traduzion
+ Traduzion
+
+ TraduzionsSielte di dâts
@@ -665,10 +693,6 @@
ObligatoriFacoltatîf
-
- Lei e modificâ i dâts dai sîts web
-
- Elimine sît webPermet par ducj i sîts
@@ -797,8 +821,6 @@
CronologjieSegnelibris
-
- CredenziâlsPasswords
@@ -823,8 +845,6 @@
The first parameter is the application name, the second is the device manufacturer name
and the third is the device model. -->
%1$s su %2$s %3$s
-
- Cjartis di creditMetodis di paiament
@@ -841,6 +861,14 @@
Schede di %s
+
+
+ Schedis di %1$s sieradis: %2$d
+
+ Viôt schedis sieradis di resint
+
Ecezions
@@ -1769,13 +1797,9 @@
Al è pussibil zontâ chest sît web ae schermade principâl dal dispositîf par doprâle cun plui sveltece, tant che e fos une aplicazion.
-
- Credenziâls e passwordsPasswords
- Salve credenziâls e passwords
-
Salve passwordsDomande prime di salvâ
@@ -1789,48 +1813,30 @@
Compile in automatic in altris aplicazionsCompile i nons utent e lis passwords in altris aplicazions dal to dispositîf.
-
- Zonte credenziâlZonte password
-
- Sincronize lis credenziâlsSincronize passwords
-
- Sincronize lis credenziâls tra dispositîfsSincronize passwords tra i tiei dispositîfs
-
- Credenziâls salvadisPasswords salvadis
- Lis credenziâls che tu salvis o sincronizis su %s a vignaran fûr achì.
-
Lis passwords salvadis o sincronizadis su %s a vignaran listadis achì. Dutis lis passwords che tu salvis a vegnin cifradis.
-
- Plui informazions su Sync.Plui informazions su la sincronizazionEcezions
-
- Lis credenziâls e lis passwords che no tu âs salvât a vignaran fûr achì.%s nol salvarà lis passwords pai sîts listâts achì.
-
- Lis credenziâls e lis passwords no vignaran salvadis par chescj sîts.%s nol salvarà lis passwords par chescj sîts.Elimine dutis lis ecezions
-
- Cîr credenziâlsCîr tes passwords
@@ -1859,17 +1865,11 @@
Mostre passwordPlate password
-
- Sbloche par visualizâ lis credenziâls salvadisSbloche par viodi lis passwords salvadis
- Protêç lis tôs credenziâls di acès
-
Protêç lis passwords salvadis
- Configure une secuence di bloc, PIN o password par protezi lis tôs credenziâls e lis passwords salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis.
-
Configure une secuence di bloc, PIN o password par protezi lis passwords salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis.Plui indenant
@@ -1885,8 +1885,6 @@
Non (A-Z)Ultime doprade
-
- Ordene il menù des credenziâlsMenù par ordenâ lis passwords
@@ -1896,41 +1894,27 @@
Compilazion automaticheRecapits
-
- Cjartis di creditMetodis di paiament
-
- Salve e compile in automatic lis cjartisSalve e compile i metodis di paiament
-
- I dâts a son cifrâts%s al cifre ducj i metodis di paiaments salvâtsSincronize lis cjartis tra plui dispositîfsSincronize cjartis di credit
-
- Zonte cjarte di creditZonte cjarte
-
- Gjestìs cjartis salvadisGjestìs cjartisZonte recapitGjestìs recapits
-
- Salve e compile in automatic i recapitsSalve e compile direzions
-
- Includi informazions come numars, e-mail e recapits di spedizionInclût numars di telefon e direzions e-mail
@@ -1954,8 +1938,6 @@
Elimine cjarte
- Eliminâ pardabon cheste cjarte di credit?
-
Eliminâ la cjarte?Elimine
@@ -1967,24 +1949,16 @@
AnuleCjartis salvadis
-
- Inserìs un numar di cjarte di credit valitInserìs un numar di cjarte valit
-
- Compile chest cjampZonte un nonSbloche par visualizâ lis cjartis di credit salvadis
-
- Protêç lis tôs cjartis di creditProtêç i metodis di paiament salvâts
- Configure une secuence di bloc, PIN o password par protezi lis tôs cjartis di credit salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis.
-
Configure une secuence di bloc, PIN o password par protezi i tiei metodis di paiament salvâts, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâju.Configure cumò
@@ -1992,8 +1966,6 @@
Plui indenantSbloche il dispositîf
-
- Sbloche par doprâ lis informazions des cjartis di credit memorizadisSbloche par doprâ i metodis di paiament
@@ -2002,12 +1974,6 @@
Modifiche recapitGjestìs recapits
-
- Non
-
- Secont non
-
- CognonNon
@@ -2033,8 +1999,6 @@
Elimine recapit
- Eliminâ pardabon chest recapit?
-
Eliminâ cheste direzion?Elimine
@@ -2132,49 +2096,29 @@
ElimineModifiche
-
- Eliminâ pardabon cheste credenziâl?Eliminâ pardabon cheste password?ElimineAnule
-
- Opzions credenziâlsOpzions password
-
- Il cjamp di test modificabil pe direzion web de credenziâl.Il cjamp di test che si pues modificâ pe direzion dal sît web.
-
- Il cjamp di test modificabil pal non utent de credenziâl.Il cjamp di test che si pues modificâ pal non utent.
- Il cjamp di test modificabil pe password de credenziâl.
-
Il cjamp di test che si pues modificâ pe password.
-
- Salve lis modifichis ae credenziâl.Salve modifichis.
-
- ModificheModifiche password
-
- Zonte gnove credenziâlZonte password
-
- Password necessarieInserìs une password
- Non utent necessari
-
Inserìs un non utentNon servidôr necessari
@@ -2524,6 +2468,8 @@
No cumòMostre origjinâl
+
+ Cjariade pagjine origjinâl no tradoteFat
@@ -2582,6 +2528,9 @@
Siere il sfuei des traduzions
+
+ Cualchi impostazion no je pal moment disponibile.
+
Traduzions
@@ -2604,6 +2553,9 @@
Selezione une lenghe par gjestî lis preferencis ”tradûs simpri“ e ”no sta tradusi mai“.
+
+ Impussibil cjariâ lis lenghis. Torne controle plui tart.
+
Propon la traduzion (predefinide)
@@ -2626,6 +2578,8 @@
Gjave %1$s
+
+ Impussibil cjariâ i sîts. Torne controle plui tart.Eliminâ %1$s?
@@ -2707,13 +2661,18 @@
Torne indaûr
+
+ Vierç scansel pal debug
+
Struments des schedisConte des schedis
- Ative
+ Ative
+
+ AtivisInative
@@ -2724,6 +2683,16 @@
Strument pe creazion di schedisNumar di schedis di creâ
+
+ Il cjamp di test al è vueit
+
+ Inserìs dome numars intîrs positîfs
+
+ Inserìs un numar plui grant di zero
+
+ Al è stât superât il numar massim di schedis (%1$s) che al è pussibil gjenerâ cuntune sole operazionZonte a schedis ativis
@@ -2740,11 +2709,11 @@
Informative su la riservatece
- Invie
+ Invie
- Siere
+ Siere
- Graciis di vê condividude la tô opinion.
+ Graciis di vê condividude la tô opinion.Une vore sodisfat(e)
@@ -2756,6 +2725,14 @@
Une vore insodisfat(e)
+
+
+ Vierç sondaç
+
+ Siere sondaç
+
+ Siere
+
Credenziâls
diff --git a/mobile/android/fenix/app/src/main/res/values-fy-rNL/strings.xml b/mobile/android/fenix/app/src/main/res/values-fy-rNL/strings.xml
index 0e0ce000f9..201fbd157c 100644
--- a/mobile/android/fenix/app/src/main/res/values-fy-rNL/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-fy-rNL/strings.xml
@@ -200,6 +200,10 @@
Add-onsUtwreidingen
+
+ Utwreidingen beheare
+
+ Mear útwreidingen ûntdekkeAccountynformaasje
@@ -219,6 +223,8 @@
Iepenje yn gewoan ljepblêdTafoegje oan startskerm
+
+ Tafoegje oan startskerm…Ynstallearje
@@ -230,9 +236,13 @@
Side oersette
+ Yn kolleksje bewarje…
+
Yn kolleksje bewarjeDiele
+
+ Diele…Iepenje yn %1$s
@@ -285,6 +295,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Bewarje
+
+ Blêdwizer foar dizze side meitsje
+
+ Blêdwizer bewurkje
+
+ Bewarje as PDF…
+
+ Lêzerwerjefte ynskeakelje
+
+ Lêzerwerjefte útskeakelje
+
+ Side oersette…
+
+ Oerset nei %1$s
+
+ Ofdrukke…
+
Gjin útwreidingen hjir
@@ -382,8 +410,6 @@
Firefox-privacyferklearring
-
- Lês mear yn ús privacyferklearringWy hâlde jo graach feilichTaal
- Oersetting
+ Oersetting
+
+ OersettingenGegevenskarren
@@ -665,10 +693,6 @@
FereaskeOpsjoneel
-
- Websitegegevens lêze en wizigje
-
- Website fuortsmiteTastean foar alle websites
@@ -793,8 +817,6 @@
SkiednisBlêdwizers
-
- OanmeldingenWachtwurden
@@ -821,8 +843,6 @@
and the third is the device model. -->
%1$s op %2$s %3$s
-
- CreditcardsBetellingsmetoaden
@@ -838,6 +858,14 @@
Ljepblêd fan %s
+
+
+ %1$s-ljepblêden sluten: %2$d
+
+ Koartlyn sluten ljepblêden besjen
+
Utsûnderingen
@@ -1759,13 +1787,9 @@
Jo kinne dizze website ienfâldich oan it startskerm fan jo apparaat tafoegje, om sa daliks tagong te hawwen en flugger te navigearjen mei in app-eftige ûnderfining.
-
- Oanmeldingen en wachtwurdenWachtwurden
- Oanmeldingen en wachtwurden bewarje
-
Wachtwurden bewarjeFreegje om te bewarjen
@@ -1780,47 +1804,28 @@
Brûkersnammen en wachtwurden yn oare apps op jo apparaat ynfolje.
-
- Oanmelding tafoegje
-
Wachtwurd tafoegje
-
- Oanmeldingen syngronisearjeWachtwurden syngronisearje
-
- Oanmeldingen op apparaten syngronisearjeWachtwurden syngronisearje tusken apparaten
-
- Bewarre oanmeldingenBewarre wachtwurden
- De oanmeldingen dy’t jo bewarje of syngronisearje mei %s wurde hjir toand.
-
De wachtwurden dy’t jo bewarje of syngronisearje mei %s sille hjir fermeld wurde. Alle wachtwurden dy’t jo bewarje binne fersifere.
-
- Mear ynfo oer Sync.Mear ynfo oer syngronisaasjeUtsûnderingen
-
- Net-bewarre oanmeldingen en wachtwurden wurde hjir werjûn.%s sil gjin wachtwurden foar de hjir fermelde websites bewarje.
-
- Oanmeldingen en wachtwurden wurde foar dizze websites net bewarre. %s sil gjin wachtwurden foar dizze websites bewarje.Alle útsûnderingen fuortsmite
-
- Oanmeldingen sykjeWachtwurden sykje
@@ -1849,17 +1854,11 @@
Wachtwurd toaneWachtwurd ferstopje
-
- Untskoattelje om jo bewarre oanmeldingen te besjenUntskoattelje om jo bewarre wachtwurden te besjen
- Befeiligje jo oanmeldingen en wachtwurden
-
Befeiligje jo bewarre wachtwurden
- Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre oanmeldingen en wachtwurden te beskermjen tsjin tagong as in oar jo apparaat hat.
-
Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre wachtwurden te beskermjen tsjin tagong as in oar jo apparaat hat.Letter
@@ -1876,8 +1875,6 @@
Namme (A-Z)Lêst brûkt
-
- Menu Oanmeldingen sortearjeWachtwurdmenu sortearje
@@ -1887,41 +1884,27 @@
Automatysk ynfoljeAdressen
-
- CreditcardsBetellingsmetoaden
- Kaarten bewarje en automatysk ynfolje
-
Betellingsmetoaden bewarje en ynfolje
-
- Gegevens binne fersifere%s fersiferet alle betellingsmetoaden dy’t jo bewarjeKaarten syngronisearje tusken apparatenKaarten syngronisearje
-
- Creditcard tafoegjeKaart tafoegje
-
- Bewarre kaarten beheareKaarten beheareAdres tafoegjeAdressen beheare
-
- Adressen bewarje en automatysk ynfoljeAdressen bewarje en ynfolje
-
- Ynformaasje lykas nûmers, e-mail- en ferstjoeradressen tafoegjeYnklusyf telefoannûmers en e-mailadressen
@@ -1946,8 +1929,6 @@
Kaart fuortsmite
- Binne jo wis dat jo dizze creditcard fuortsmite wolle?
-
Kaart fuortsmite?Fuortsmite
@@ -1961,23 +1942,14 @@
Bewarre kaarten
-
- Fier in jildich creditkaartnûmer yn
-
Fier in jildich kaartnûmer yn
-
- Folje dit fjild ynFoegje in namme taUntskoattelje om jo bewarre kaarten te besjen
- Befeiligje jo creditcards
-
Befeiligje jo bewarre betelmetoaden
-
- Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre creditcards te beskermjen tsjin tagong as in oar jo apparaat hat.Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre betellingsmetoaden te beskermjen tsjin tagong as in oar jo apparaat hat.
@@ -1988,9 +1960,6 @@
Untskoattelje jo apparaat
-
- Untskoattelje om bewarre creditkaartynformaasje te brûken
-
Untskoattelje om bewarre betellingsmetoaden te brûken
@@ -1999,12 +1968,6 @@
Adres bewurkjeAdressen beheare
-
- Foarnamme
-
- Twadde namme
-
- EfternammeNamme
@@ -2030,8 +1993,6 @@
Adres fuortsmite
-
- Binne jo wis dat jo dit adres fuortsmite wolle?Dit adres fuortsmite?
@@ -2130,49 +2091,29 @@
FuortsmiteBewurkje
-
- Binne jo wis dat jo dizze oanmelding fuortsmite wolle?Binne jo wis dat jo dit wachtwurd fuortsmite wolle?FuortsmiteAnnulearje
-
- OanmeldopsjesWachtwurdopsjes
-
- It bewurkbere tekstfjild foar it webadres fan de oanmelding.It bewurkbere tekstfjild foar it websiteadres.
-
- It bewurkbere tekstfjild foar de brûkersnamme fan de oanmelding.It bewurkbere tekstfjild foar de brûkersnamme.
- It bewurkbere tekstfjild foar it wachtwurd fan de oanmelding.
-
It bewurkbere tekstfjild foar it wachtwurd.
-
- Wizigingen oan oanmelding bewarje.Wizigingen bewarje.
-
- BewurkjeWachtwurd bewurkje
-
- Nije oanmelding tafoegjeWachtwurd tafoegje
-
- Wachtwurd fereaskeFolje in wachtwurd yn
- Brûkersnamme fereaske
-
Folje in brûkersnamme ynHostnamme fereaske
@@ -2524,6 +2465,8 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
No netOrizjineel toane
+
+ Oarspronklik net-oersette side ladenDien
@@ -2580,6 +2523,9 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
Blêd Oersettingen slute
+
+ Guon ynstellingen binne tydlik net beskikber.
+
Oersettingen
@@ -2602,6 +2548,9 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
Selektearje in taal om de foarkarren ‘Altyd oersette’ en ‘Nea oersette’ te behearen.
+
+ Kin talen net lade. Probearje it letter nochris.
+
Oanbiede om oer te setten (standert)
@@ -2624,6 +2573,8 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
%1$s fuortsmite
+
+ Kin websites net lade. Probearje it letter nochris.%1$s fuortsmite?
@@ -2702,13 +2653,18 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
Tebek blêdzje
+
+ Debuglade iepenje
+
LjepblêdhelpmiddelenOantal ljepblêden
- Aktyf
+ Aktyf
+
+ AktyfYnaktyf
@@ -2719,6 +2675,16 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
Helpmiddel foar it oanmeitsjen fan ljepblêdenOantal oan te meitsjen ljepblêden
+
+ Tekstfjild is leech
+
+ Fier allinnich positive hiele getallen yn
+
+ Fier in getal grutter dan nul yn
+
+ Dit binne mear as it maksimale oantal ljepblêden (%1$s) dat yn ien bewurking oanmakke wurde kinTafoegje oan aktive ljepblêden
@@ -2735,11 +2701,11 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
Privacyferklearring
- Yntsjinje
+ Yntsjinje
- Slute
+ Slute
- Tank foar jo kommentaar!
+ Tank foar jo kommentaar!Hiel tefreden
@@ -2751,6 +2717,14 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
Hiel ûntefreden
+
+
+ Enkête iepenje
+
+ Enkête slute
+
+ Slute
+
Oanmeldingen
diff --git a/mobile/android/fenix/app/src/main/res/values-gl/strings.xml b/mobile/android/fenix/app/src/main/res/values-gl/strings.xml
index 10e350b1c0..8f2f036b83 100644
--- a/mobile/android/fenix/app/src/main/res/values-gl/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-gl/strings.xml
@@ -196,6 +196,10 @@
ComplementosExtensións
+
+ Xestionar as extensións
+
+ Descubre máis extensiónsInformación da conta
@@ -214,6 +218,8 @@
Abrir na pestana normalEngadir á páxina de inicio
+
+ Engadir á pantalla de inicio…Instalar
@@ -225,9 +231,13 @@
Traducir a páxina
+ Gardar na colección…
+
Gardar na colecciónCompartir
+
+ Compartir…Aberto en %1$s
@@ -279,6 +289,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Gardar
+
+ Marcar esta páxina
+
+ Editar marcador
+
+ Gardar como PDF…
+
+ Activa a vista de lector
+
+ Desactiva a vista de lector
+
+ Traducir a páxina…
+
+ Traducido a %1$s
+
+ Imprimir…
+
Non hai extensións aquí
@@ -374,8 +402,6 @@
Política de privacidade de Firefox
-
- Obtéña máis información no noso aviso de privacidadeEncántanos telo seguroIdioma
- Tradución
+ Tradución
+
+ TraduciónsEscollas de datos
@@ -655,10 +683,6 @@
ObrigatorioOpcional
-
- Le e cambia os datos do sitio web
-
- Eliminar sitio webPermitir para todos os sitios
@@ -783,8 +807,6 @@
HistorialMarcadores
-
- IdentificaciónsContrasinais
@@ -810,8 +832,6 @@
and the third is the device model. -->
%1$s en %2$s %3$s
-
- Tarxetas de créditoMétodos de pago
@@ -827,6 +847,14 @@
Lapela de %s
+
+
+ %1$s pestanas pechadas: %2$d
+
+ Ver pestanas pechadas recentemente
+
Excepcións
@@ -1747,13 +1775,9 @@
Pode engadir facilmente este sitio web á pantalla de inicio do dispositivo para ter acceso instantáneo e navegar máis rápido cunha experiencia semellante á dunha aplicación.
-
- Identificacións e contrasinaisContrasinais
- Gardar Inicios de sesión e contrasinais
-
Gardar contrasinaisPreguntar para gardar
@@ -1768,46 +1792,28 @@
Completado automático noutras aplicaciónsEncher os nomes de usuario e os contrasinais noutras aplicacións do dispositivo.
-
- Engadir credenciaisEngadir contrasinal
-
- Sincronizar os inicios de sesiónSincronizar contrasinais
-
- Sincronizar as credenciais entre dispositivosSincronizar os contrasinais entre dispositivos
-
- Identificacións gardadasContrasinais gardados
- Os inicios de sesión que garde ou sincronice co %s aparecerán aquí.
-
Os contrasinais que garde ou sincronice con %s listaranse aquí. Todos os contrasinais que garde están cifrados.
-
- Obteña máis información sobre Sync.Obteña máis información sobre SyncExcepcións
-
- Aquí mostraranse os inicios de sesión e os contrasinais que non se garden.%s non gardará os contrasinais dos sitios que aparecen aquí.
-
- Non se gardarán os inicios de sesión e os contrasinais para estes sitios.%s non gardará os contrasinais destes sitios.Eliminar todas as excepcións
-
- Buscar inicios de sesiónsBuscar contrasinais
@@ -1836,17 +1842,11 @@
Mostrar contrasinalAgochar contrasinal
-
- Desbloquee para ver os seus inicios de sesión gardadosDesbloquear para ver os seus contrasinais gardados
- Protexa os seus inicios de sesión e contrasinais
-
Protexa os seus contrasinais gardados
- Configure un padrón de bloqueo de dispositivo, PIN ou contrasinal para protexer os accesos e contrasinais gardados de que non sexan accedidos se outra persoa ten o seu dispositivo.
-
Configure un padrón de bloqueo do dispositivo, un PIN ou un contrasinal para protexer o acceso aos seus contrasinais gardados se outra persoa ten o seu dispositivo.Máis tarde
@@ -1862,8 +1862,6 @@
Nome (A-Z)Usado por última vez
-
- Ordenar o menú de inicio de sesiónMenú de ordenar contrasinais
@@ -1873,16 +1871,10 @@
Completado automáticoEnderezos
-
- Tarxetas de créditoMétodos de pagamento
- Gardar e completar automaticamente as tarxetas
-
Gardar e cubrir os métodos de pago
-
- Os datos están cifrados%s cifra todos os métodos de pago que garda
@@ -1890,12 +1882,8 @@
Sincronizar as tarxetas entre dispositivosSincronizar as tarxetas
-
- Engadir unha tarxeta de créditoEngadir a tarxeta
-
- Xestionar as tarxetas gardadasXestionar tarxetas
@@ -1904,12 +1892,8 @@
Xestionar enderezos
-
- Gardar e encher automaticamente enderezosGardar e completar os enderezos
-
- Inclúe información como números, correo electrónico e enderezos de envíoInclúe números de teléfono e enderezos de correo electrónico
@@ -1933,8 +1917,6 @@
Eliminar a tarxeta
- Seguro de que quere eliminar esta tarxeta de crédito?
-
Eliminar a tarxeta?Eliminar
@@ -1946,23 +1928,15 @@
CancelarTarxetas gardadas
-
- Introduza un número de tarxeta válidoIntroduza un número de tarxeta válido
-
- Cubra este campoEngadir un nomeDesbloquee para ver as súas tarxetas gardadas
- Asegure as súas tarxetas de crédito
-
Protexa os seus métodos de pago gardados
- Configure un padrón de bloqueo de dispositivo, PIN ou contrasinal para evitar que outra persoa co seu dispositivo poida acceder a elas.
-
Configure un padrón de bloqueo do dispositivo, un PIN ou un contrasinal para protexer o acceso aos seus métodos de pago gardados se outra persoa ten o seu dispositivo.Configurar agora
@@ -1970,8 +1944,6 @@
Máis tardeDesbloquear o dispositivo
-
- Desbloquee para empregar a información almacenada de tarxetas de créditoDesbloquee para usar os métodos de pago gardados
@@ -1980,12 +1952,6 @@
Editar enderezoXestionar enderezos
-
- Nome
-
- Segundo nome
-
- ApelidosNome
@@ -2011,8 +1977,6 @@
Eliminar enderezo
- Seguro de que quere eliminar este enderezo?
-
Eliminar este enderezo?Eliminar
@@ -2112,49 +2076,29 @@
EliminarEditar
-
- Confirma que desexa eliminar este inicio de sesión?Seguro que quere eliminar este contrasinal?EliminarCancelar
-
- Opcións de inicio de sesiónOpcións de contrasinal
-
- O campo de texto editábel para o enderezo web do inicio de sesión.O campo de texto editable para o enderezo do sitio web.
-
- O campo de texto editábel para o nome de usuario do inicio de sesión.O campo de texto editable para o nome de usuario.
- O campo de texto editábel para o contrasinal do inicio de sesión.
-
O campo de texto editable para o contrasinal.
-
- Gardar os cambios para iniciar sesión.Gardar cambios.
-
- EditarEditar contrasinal
-
- Engadir novas credenciaisEngadir contrasinal
-
- Contrasinal obrigatorioIntroduza un contrasinal
- Requírese un nome de usuario
-
Introduza un nome de usuarioRequírese un nome de servidor
@@ -2556,6 +2500,9 @@
Pechar a folla de traducións
+
+ Algunhas opcións de configuración non están dispoñibles temporalmente.
+
Traducións
@@ -2579,6 +2526,9 @@
Seleccionar un idioma para xestionar as preferencias de «traducir sempre» e «nunca traducir».
+
+ Non se puideron cargar os idiomas. Volve a comprobar máis tarde.
+
Ofrecer traducción (predeterminado)
@@ -2602,6 +2552,8 @@
Retirar %1$s
+
+ Non se puideron cargar os sitios. Volve a comprobar máis tarde.Eliminar %1$s?
@@ -2679,13 +2631,18 @@
Retroceder no historial
+
+ Abre o caixón de depuración
+
Ferramentas de lapelasNúmero de lapelas
- Activo
+ Activo
+
+ ActivoInactivo
@@ -2696,6 +2653,16 @@
Ferramenta de creación de lapelasCantidade de lapelas a crear
+
+ O campo de texto está baleiro
+
+ Introduce só números enteiros positivos
+
+ Introduce un número maior que cero
+
+ Superouse o número máximo de pestanas (%1$s) que se poden xerar nunha soa operaciónEngadir ás lapelas activas
@@ -2712,11 +2679,11 @@
Política de privacidade
- Enviar
+ Enviar
- Pechar
+ Pechar
- Grazas pola súa opinión
+ Grazas pola súa opiniónMoi satisfeito
@@ -2728,6 +2695,14 @@
Moi insatisfeito
+
+
+ Enquisa aberta
+
+ Pecha enquisa
+
+ Pechar
+
Identificacións
diff --git a/mobile/android/fenix/app/src/main/res/values-gn/strings.xml b/mobile/android/fenix/app/src/main/res/values-gn/strings.xml
index a83bce8a53..ae524cde42 100644
--- a/mobile/android/fenix/app/src/main/res/values-gn/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-gn/strings.xml
@@ -203,6 +203,10 @@
MoĩmbahaJepysokue
+
+ Eñangareko jepysokuére
+
+ Ejuhuvéta jepysokueMba’ete marandu
@@ -222,6 +226,8 @@
Embojuruja tendaykeEmbojuaju mba’erechaha ñepyrũgua
+
+ Embojuaju mba’erechaha ñepyrũgua…Mohenda
@@ -233,9 +239,13 @@
Emoñe’ẽasa kuatiarogue
+ Eñongatu mbyatyhápe…
+
Eñongatu mbyatyhápeMoherakuã
+
+ Moherakuã…Embojuruja %1$s-pe
@@ -289,6 +299,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Ñongatu
+
+ Emongurusu ko kuatiarogue
+
+ Embosako’i techaukaha
+
+ Eñongatu PDF ramo…
+
+ Emyandy moñe’ẽha jehecha
+
+ Embogue moñe’ẽha jehecha
+
+ Emoñe’ẽasa kuatiarogue…
+
+ %1$s-pe oñemoñe’ẽasapyre
+
+ Mbokuatia…
+
Ndaipóri jepysokue ápe
@@ -385,8 +413,6 @@
Firefox marandu’i ñemigua
-
- Eikuaave ore marandu’i ñemigua rupiveRovy’ã eimére tekorosãmeÑe’ẽ
- Ñemoñe’ẽasa
+ Ñemoñe’ẽasa
+
+ Ñemoñe’ẽasaMba’ekuaarã jeporavo
@@ -672,10 +700,6 @@
Jeporavorã
-
- Emoñe’ẽ ha emoambue ñanduti renda mba’ekuaarã
-
- Emboguete ñanduti rendaEmoneĩ opaite tendápe g̃uarã
@@ -807,8 +831,6 @@
Techaukaha
-
- Tembiapo ñepyrũÑe’ẽñemi
@@ -835,8 +857,6 @@
and the third is the device model. -->
%1$s %2$s %3$s-pe
-
- Kuatia’atã ñemurãMba’éicha ehepyme’ẽta
@@ -852,6 +872,14 @@
Tendayke %s mba’e
+
+
+ %1$s tendayke mbotypyre: %2$d-pe
+
+ Ehecha tendayke oñembotyramóva
+
Oĩ’ỹva
@@ -1803,13 +1831,9 @@
Ikatu embojuaju ko ñanduti renda ne mba’e’oka mba’erechaha ñepyrũgua rehe eike hag̃ua ha eikundaha pya’eve, peteĩ tembiporu’ícharamo.
-
- Tembiapo ñepyrũ ha ñe’ẽñemiÑe’ẽñemi
- Eñongatu tembiapo ñepyrũ ha ñe’ẽñemi
-
Eñongatu ñe’ẽñemiEjerure ñemoneĩ eñongatu hag̃ua
@@ -1826,46 +1850,27 @@
Emoĩmba ha eñongatu poruhára réra ha ñe’ẽñemi ambue tembiporu’ípe ne mba’e’oka pegua.
-
- Embojuaju jeike
-
Embojuaju ñe’ẽñemi
-
- Embojuehe tembiapo ñepyrũEmbojuehe ñe’ẽñemi
-
- Embojuehe tembiapo ñepyrũ mba’e’oka pa’ũmeEmbojuehe ñe’ẽñemi mba’e’oka pa’ũme
-
- Tembiapo ñepyrũ ñongatupyreÑe’ẽñemi ñongatupyre
- Ko’ápe ojehecháta tembiapo ñepyrũ eñongatu térã embojuehéva %s ndive.
-
Umi ñe’ẽñemi eñongatu térã embojuehéva %s ndive ojehecháta ko’ápe. Opaite ñe’ẽñemi eñongatúva ipapapýta.
-
- Eikuaave Sync reheguaEikuaave ñembojuehe reheguaOĩ’ỹva
-
- Ápe ojehecháta tembiapo ñepyrũ ha ñe’ẽñemi oñeñongatu’ỹva.%s noñongatúi ñe’ẽñemi tendakuéra hysýiva ko’ápe g̃uarãme.
-
- Noñeñongatumo’ãi tembiapo ñepyrũ ha ñe’ẽñemi ko’ã tendápe g̃uarã.%s noñongatúi ñe’ẽñemi ko’ã tendápe g̃uarã.Emboguete opaite oĩ’ỹva
-
- Eheka tembiapo ñepyrũEheka ñe’ẽñemi
@@ -1894,17 +1899,11 @@
Ehechauka ñe’ẽñemiEmokañy ñe’ẽñemi
-
- Emyandyjey ehecha hag̃ua ne rembiapo ñepyrũ ñongatupyreEmbojuruja ehecha hag̃ua ñe’ẽñemi ñongatupyre
- Erekokuaa nde poruhára ha ñe’ẽñemi
-
Emo’ã ne ñe’ẽñemi ñongatupyre
- Emboheko pe patrõ jokoháva mba’e’oka pegua, PIN térã ñe’ẽñemi emo’ã hag̃ua nde poruhára ha ñe’ẽñemi ñongatupyrépe jeike ambue orekórõ ne mba’e’oka.
-
Emboheko mba’e’oka jekokoha rape, PIN térã ñe’ẽñemi emo’ã hag̃ua ñe’ẽñemi ñongatupyre ha emboyke ani hag̃ua oike ambuéva orekórõ ne mba’e’oka.Upéi
@@ -1923,8 +1922,6 @@
Téra (A-Z)Jejuru paha
-
- Emoĩporã poravorã tembiapo ñepyrũguaEmoĩporã ñe’ẽñemi poravorã
@@ -1934,43 +1931,29 @@
Myanyhẽ jeheguiKundaharape
-
- Kuatia’atã ñemurãMba’éicha ehepyme’ẽta
-
- Eñongatu ha emyanyhẽ kuatia’atãEñongatu ha emyanyhẽ mba’éicha ehepyme’ẽta
-
- Mba’ekuaarã ipapapypa%s ombopapapypa ne ñehepyme’ẽrã ñongatupyreEmbojuehe kuatia’atã mba’e’oka pa’ũmeEmbojuehe kuatia’atã
-
- Embojuaju kuatia’atã ñemurãEmbojuaju kuatia’atã
-
- Eñangareko kuatia’atã ñongatupyréreEñangareko kuatia’atãEmbojuaju kundaharapeKundaharape ñangareko
-
- Eñongatu ha emyanyhẽ kundaharapeEñongatu ha emyanyhẽ kundaharape
-
- Emoĩ marandu ipapapy, ñanduti veve ha kundaharape ñemondorãvaOike pumbyry papapy ha ñanduti veve kundaharape
@@ -1994,8 +1977,6 @@
Emboguete kuatia’atã
- ¿Emboguesépa añetehápe ko kuatia’atã ñemurã?
-
¿Emboguete kuatia’atã?Mboguete
@@ -2009,24 +1990,15 @@
Kuatia’atã ñongatupyre
-
- Ikatúpiko ehai kuatia’atã ñemurã papapy oikóva
-
Emoinge kuatia’atã papapy oikóva
-
- Ikatúpiko emyanyhẽ ko koraEmbojuaju téraEmbojuruja ehecha hag̃ua kuatia’atã ñongatupyre
- Emohekorosã nde kuatia’atã ñemurã
-
Emo’ã ne ñehepyme’ẽrã ñongatupyre
- Emboheko peteĩ jekokoha rape, PIN térã ñe’ẽñemi emo’ã hag̃ua nde kuatia’atã ñongatupyre ambue oikeséramo ne mba’e’okápe.
-
Emboheko mba’e’oka jekokoha rape, PIN térã ñe’ẽñemi emo’ã hag̃ua ñehepyme’ẽrã ñongatupyre ha emboyke ani hag̃ua oike ambuéva orekórõ ne mba’e’oka.Emboheko ko’ág̃a
@@ -2035,9 +2007,6 @@
Embojuruja ne mba’e’oka
-
- Embojuruja eiporu hag̃ua kuatia’atã ñemurã marandu mbyatypyre
-
Embojuruja eiporu hag̃ua ne ñehepyme’ẽrã ñongatupyre
@@ -2046,12 +2015,6 @@
Embosako’i kundaharapeKundaharape ñangareko
-
- Téra Peteĩha
-
- Téra Mokõiha
-
- TerajoapyTéra
@@ -2077,8 +2040,6 @@
Embogue kundaharape
-
- ¿Añetehápepa remboguese ko kundaharape?¿Embogue kundaharape?
@@ -2179,49 +2140,29 @@
MbogueteMbosako’i
-
- ¿Emboguese añetehápe ko tembiapo ñepyrũ?Emboguesetépa añetehápe ko ñe’ẽñemiMbogueteHeja
-
- Jeporavorã tembiapo ñepyrũguaÑe’ẽñemi jeporavorã
-
- Moñe’ẽha kora isako’ikuaáva ñanduti kundaharape rembiapo ñepyrũme.Moñe’ẽrã kora ehaikuaáva kundaharape ñanduti rendápe g̃uarã.
-
- Moñe’ẽha kora isako’ikuaáva poruhára réra rembiapo ñepyrũme.Moñe’ẽrã kora ehaikuaáva poruhára rérape g̃uarã.
- Moñe’ẽha kora isako’ikuaáva ñe’ẽñemi rembiapo ñepyrũme.
-
Moñe’ẽrã kora ehaikuaáva ñe’ẽñemíme g̃uarã.
-
- Eñongatu moambue tembiapo ñepyrũme.Moambue ñongatu.
-
- Mbosako’iEmbosako’i ñe’ẽñemi
-
- Embojuaju terarenda pyahuEmbojuaju ñe’ẽñemi
-
- Tekotevẽ ñe’ẽñemiEmoinge ñe’ẽñemi
- Poruhára réra jerurepyre
-
Ehai poruhára réraMohendahavusu réra jerurepyre
@@ -2573,6 +2514,8 @@
Ani ko’ág̃aEhechauka ypykuéva
+
+ Oñemyanyhẽ kuatiarogue oñemoñe’ẽasa’ỹreOĩma
@@ -2632,6 +2575,9 @@
Emboty ñe’ẽasaha rogue
+
+ Ñemoĩporãha ndojeporukuaáiva ko’ag̃aite.
+
Ñemoñe’ẽasa
@@ -2657,6 +2603,9 @@
Eiporavo ñe’ẽ eñangareko hag̃ua umi erohoryvéva “emoñe’ẽasameme” y “ani emoñe’ẽasa”.
+
+ Noñemyanyhẽkuaái ñe’ẽnguéra. Eha’ãjey ag̃amieve.
+
Eikuave’ẽ ñe’ẽasa (ypyguáva)
@@ -2680,6 +2629,8 @@
Emboguete %1$s
+
+ Noñemyanyhẽkuaái tendakuéra. Eha’ãjey ag̃ave.¿Emboguete %1$s?
@@ -2757,13 +2708,18 @@
Eikundaha tapykuévo
+
+ Embojuruja kahõ mopotĩha
+
Tendayke rembiporuTendayke papapy
- Myandy
+ Myandy
+
+ MyandyJokopyre
@@ -2774,6 +2730,16 @@
Tembiporu tendayke moheñoihaMboýpa emoheñóita tendayke
+
+ Moñe’ẽrã kora inandi
+
+ Emoinge papapy entero positivo año
+
+ Emoinge pateĩ papapy sérogui tuichavéva
+
+ Ohasáma pe tendayke oñekotevẽva (%1$s) ikatúva oñemongu’e peteĩjeýpeEmbojuaju tendayke oikóva
@@ -2790,11 +2756,11 @@
Marandu’i ñemiguáva
- Mondo
+ Mondo
- Mboty
+ Mboty
- ¡Aguyje nde jehaipyrére!
+ ¡Aguyje nde jehaipyrére!Avy’aiterei
@@ -2807,6 +2773,14 @@
Nachembovy’ái
+
+
+ Embojuruja ñeporandu
+
+ Emboty ñeporandu
+
+ Mboty
+
Tembiapo moñepyrũ
diff --git a/mobile/android/fenix/app/src/main/res/values-hr/strings.xml b/mobile/android/fenix/app/src/main/res/values-hr/strings.xml
index d1834444f2..a89e528b94 100644
--- a/mobile/android/fenix/app/src/main/res/values-hr/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-hr/strings.xml
@@ -2,7 +2,7 @@
- Privatni %s
+ Privatne %s%s (privatno)
@@ -49,12 +49,12 @@
- Nedavno spremljeno
+ Nedavno spremljeno
- Prikaži sve spremljene zabilješke
+ Prikaži sve spremljene zabilješke
- Ukloni
+ Ukloni%1$s proizvodi Mozilla.
@@ -144,8 +144,8 @@
Nova privatna kartica
-
- Prečac za lozinke
+
+ Prečac za lozinke
@@ -187,11 +187,11 @@
Zaustavi
- Dodaci
+ DodaciInformacije računa
- Ovdje nema dodataka
+ Ovdje nema dodatakaPomoć
@@ -207,7 +207,7 @@
Dodaj na početni ekran
- Instaliraj
+ InstalirajPonovna sinkronizacija
@@ -313,22 +313,22 @@
- Obavijesti vam pomažu da učinite više s %s
+ Obavijesti vam pomažu da učinite više s %s
- Sinkronizirajte svoje kartice između uređaja, upravljajte preuzimanjima, dobivajte savjete o tome kako najbolje iskoristiti %s zaštitu privatnosti i još mnogo toga.
+ Sinkronizirajte svoje kartice između uređaja, upravljajte preuzimanjima, dobivajte savjete o tome kako najbolje iskoristiti %s zaštitu privatnosti i još mnogo toga.
- Nastavi
+ Nastavi
- Ne sada
+ Ne sadaVolimo vas čuvati
- Naš neprofitni preglednik pomaže spriječiti tvrtke da vas tajno prate na webu.\n\nSaznajte više u našoj obavijesti o privatnosti.
+ Naš neprofitni preglednik pomaže spriječiti tvrtke da vas tajno prate na webu.\n\nSaznajte više u našoj obavijesti o privatnosti.
- politika privatnosti
+ politika privatnostiPostavi kao zadani preglednik
@@ -511,7 +511,7 @@
Zatvaranje aplikacije radi primjene promjena…
- Dodaci
+ DodaciObavijesti
@@ -523,7 +523,7 @@
- Prilagođena kolekcija dodataka
+ Prilagođena kolekcija dodatakaU redu
@@ -533,13 +533,13 @@
Vlasnik kolekcije (ID korisnika)
- Izmijenjena je kolekcija dodataka. Napuštanje aplikacije za primjenu izmjena…
+ Izmijenjena je kolekcija dodataka. Napuštanje aplikacije za primjenu izmjena…Vrati se natrag
- Nedavne zabilješke
+ Nedavne zabilješkeNedavno posjećeno
@@ -587,15 +587,15 @@
Istražite više pozadina
-
+
- Dodaci su privremeno onemogućeni
+ Dodaci su privremeno onemogućeni
- Jedan ili više dodataka prestalo je raditi, što je vaš sustav učinilo nestabilnim. %1$s je bezuspješno pokušao ponovno pokrenuti dodatke.\n\nDodaci se neće ponovno pokrenuti tijekom vaše trenutačne sesije.\n\nUklanjanje ili onemogućavanje dodataka može riješiti ovaj problem.
+ Jedan ili više dodataka prestalo je raditi, što je vaš sustav učinilo nestabilnim. %1$s je bezuspješno pokušao ponovno pokrenuti dodatke.\n\nDodaci se neće ponovno pokrenuti tijekom vaše trenutačne sesije.\n\nUklanjanje ili onemogućavanje dodataka može riješiti ovaj problem.
- Pokušajte ponovno pokrenuti dodatke
+ Pokušajte ponovno pokrenuti dodatke
- Nastavite s onemogućenim dodacima
+ Nastavite s onemogućenim dodacima
@@ -608,8 +608,6 @@
PovijestZabilješke
-
- PrijaveOtvorene kartice
@@ -635,8 +633,6 @@
and the third is the device model. -->
%1$s na %2$s %3$s
-
- Kreditne karticeAdrese
@@ -1571,10 +1567,6 @@
Ovu stranicu lako možeš dodati na početni zaslon svog uređaja za brže pretraživanje s iskustvom sličnim aplikacijama.
-
- Prijave i lozinke
-
- Spremi prijave i lozinkePitaj treba li se spremiti
@@ -1588,30 +1580,11 @@
Ispuni korisnička imena i lozinke u drugim aplikacijama na tvom uređaju.
-
- Dodaj prijavu
-
-
- Sinkroniziraj prijave
-
- Sinkroniziraj prijave na svim uređajima
-
- Spremljene prijave
-
- Ovdje će se prikazati prijave koje spremaš ili sinkroniziraš s programom %s.
-
- Saznaj više o sinkronizaciji.Iznimke
-
- Ovdje će se prikazati prijave i lozinke koje nisu spremljene.
-
- Prijave i lozinke neće se spremiti za te web-stanice.Obriši sve iznimke
-
- Traži prijaveStranica
@@ -1638,13 +1611,7 @@
Prikaži lozinkuSakrij lozinku
-
- Otključaj za pregled tvojih spremljenih prijava
-
- Osiguraj svoje prijave i lozinke
-
- Postavi način za zaključavanje uređaja, PIN-a ili lozinke, kako bi se spriječio pristup spremljenim prijavama i lozinkama, kad netko drugi radi s tvojim uređajem.Kasnije
@@ -1661,40 +1628,22 @@
Naziv (A-Z)Zadnja upotreba
-
- Izbornik sortiranja prijavaAutomatsko ispunjavanjeAdrese
-
- Kreditne kartice
-
- Spremi i automatski ispuni polja kartice
-
- Podaci su šifriraniSinkroniziraj kartice na uređajimaSinkroniziraj kartice
-
- Dodaj kreditnu karticu
-
-
- Upravljaj spremljenim karticamaDodaj adresuUpravljaj adresama
-
- Spremi i automatski ispuni adrese
-
- Uključi podatke kao što su brojevi, e-pošta i adresa dostave
-
Dodaj karticu
@@ -1713,8 +1662,6 @@
Izbriši karticuIzbriši karticu
-
- Jeste li sigurni da želite obrisati ovu karticu?Izbriši
@@ -1727,17 +1674,8 @@
Spremljene kartice
-
- Unesi važeći broj kreditne kartice
-
-
- Molimo ispuni ovo poljeOtključaj za prikaz spremljenih kreditnih kartica
-
- Osiguraj svoje kreditne kartice
-
- Postavi uzorak za otključavanje uređaja, PIN ili lozinku da bi tvoje spremljene kreditne kartice bile zaštićene od neovlaštenog pristupa drugih osoba.Postavi sada
@@ -1745,21 +1683,12 @@
Otključaj svoj uređaj
-
- Otključ za korištenje spremljenih podataka o kreditnim karticama
-
Dodaj adresuUredi adresuUpravljaj adresama
-
- Ime
-
- Srednje ime
-
- PrezimeUlica
@@ -1783,8 +1712,6 @@
OdustaniIzbriši adresu
-
- Stvano želiš izbrisati ovu adresu?Izbriši
@@ -1883,30 +1810,10 @@
IzbrišiUredi
-
- Sigurno izbrisati ovu prijavu?IzbrišiOdustani
-
- Opcije prijave
-
- Tekstualno polje za web adresu prijave koje se može uređivati.
-
- Tekstualno polje za korisničko ime koje se može uređivati.
-
- Tekstualno polje za lozinku koje se može uređivati.
-
- Spremi izmjene prijave.
-
- Uređivanje
-
- Dodaj novu prijavu
-
- Potrebna je lozinka
-
- Korisničko ime je potrebnoDomena je potrebna
@@ -2004,7 +1911,7 @@
%s pretraga
-
+
Postavi automatsko otvaranje poveznica web stranica, e-pošte i poruka u Firefoxu.
@@ -2014,7 +1921,7 @@
Klikni za više informacija
- Navigiraj gore
+ Navigiraj goreZatvori
@@ -2056,4 +1963,6 @@
+
+
diff --git a/mobile/android/fenix/app/src/main/res/values-hsb/strings.xml b/mobile/android/fenix/app/src/main/res/values-hsb/strings.xml
index b366c59fcd..561485718b 100644
--- a/mobile/android/fenix/app/src/main/res/values-hsb/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-hsb/strings.xml
@@ -200,6 +200,10 @@
PřidatkiRozšěrjenja
+
+ Rozšěrjenja rjadować
+
+ Dalše rozšěrjenja namakaćKontowe informacije
@@ -218,6 +222,8 @@
W normalnym rajtarku wočinićStartowej wobrazowce přidać
+
+ Startowej wobrazowce přidać…Instalować
@@ -229,9 +235,13 @@
Stronu přełožić
+ Do zběrki składować…
+
Do zběrki składowaćDźělić
+
+ Dźělić…W %1$s wočinić
@@ -284,6 +294,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Składować
+
+ Tutu stronu jako zapołožku składować
+
+ Zapołožku wobdźěłać
+
+ Jako PDF składować…
+
+ Čitanski napohlad zmóžnić
+
+ Čitanski napohlad znjemóžnić
+
+ Stronu přełožić…
+
+ Přełoženy do rěče %1$s
+
+ Ćišćeć…
+
Žane rozšěrjenja tu
@@ -379,8 +407,6 @@
Zdźělenka priwatnosće Firefox
-
- Zhońće wjace w našej zdźělence priwatnosćeŠkitamy was radyRěč
- Přełožk
+ Přełožk
+
+ PřełožkiDatowe wuběry
@@ -661,10 +689,6 @@
TrěbnyNa přeće
-
- Websydłowe daty čitać a změnić
-
- Websydło zhašećZa wšě sydła dowolić
@@ -791,8 +815,6 @@
HistorijaZapołožki
-
- PřizjewjenjaHesła
@@ -820,8 +842,6 @@
and the third is the device model. -->
%1$s wot %2$s %3$s
-
- Kreditne kartyPłaćenske metody
@@ -837,6 +857,14 @@
Rajtark z %s
+
+
+ Rajtarki %1$s začinjene: %2$d
+
+ Runje začinjene rajtarki pokazać
+
Wuwzaća
@@ -1768,13 +1796,9 @@
Móžeće startowej wobrazowce swojeho grata tute websydło lochko přidać, zo byšće direktny přistup měł a spěšnišo z dožiwjenjom nałoženja přehladował.
-
- Přizjewjenja a hesłaHesła
- Přizjewjenja a hesła składować
-
Hesła składowaćPřed składowanjom so prašeć
@@ -1790,46 +1814,27 @@
Wužiwarske mjena a hesła w druhich nałoženjach na wašim graće zasadźić.
-
- Přizjewjenje přidać
-
Hesło přidać
-
- Přizjewjenja synchronizowaćHesła synchronizować
-
- Přizjewjenja mjez gratami synchronizowaćHesła přez graty synchronizować
-
- Składowane přizjewjenjaSkładowane hesła
- Přizjewjenja, kotrež składujeće abo z %s synchronizujeće, so tu pokazaja.
-
Hesła, kotrež składujeće abo z %s synchronizujeće, so tu nalistuja. Wšě hesła, kotrež składujeće, so zaklučuja.
-
- Zhońće wjace wo Sync.Zhońće wjace wo syncWuwzaća
-
- Přizjewjenja a hesła, kotrež so njeskładuja, so tu pokazaja.%s hesła za sydła njeskładuje, kotrež su tu nalistowane.
-
- Přizjewjenja a hesła so za tute sydła njeskładuja.%s hesła za tute sydła njeskładuje.Wšě wuwzaća zhašeć
-
- Přizjewjenja pytaćHesła přepytać
@@ -1858,17 +1863,11 @@
Hesło pokazaćHesło schować
-
- Za zwobraznjenje wašich składowanych přizjewjenjow wotewrěćZa zwobraznjenje wašich składowanych hesłow wotewrěć
- Zawěsćće swoje přizjewjenja a hesła
-
Zawěsćće swoje składowane hesła
- Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym přizjewjenjam a hesłam zadźěwał, jeli něchtó druhi waš grat ma.
-
Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym hesłam zadźěwał, jeli něchtó druhi waš grat ma.Pozdźišo
@@ -1887,9 +1886,6 @@
Poslednim wužiću
-
- Meni přizjewjenskich datow sortěrować
-
Meni „Hesła sortěrować“
@@ -1898,41 +1894,27 @@
Awtomatisce wupjelnićAdresy
-
- Kreditne kartyPłaćenske metody
- Karty składować a awtomatisce wupjelnić
-
Płaćenske metody składować a wupjelnić
-
- Daty su zaklučowane%s wšě płaćenske metody zaklučuje, kotrež składujećeKarty přez graty synchronizowaćKarty synchronizować
-
- Kreditnu kartu přidaćKartu přidać
-
- Składowane karty rjadowaćKarty rjadowaćAdresu přidaćAdresy rjadować
-
- Adresy składować a awtomatisce wupjelnićAdresy składować a wupjelnić
-
- Informacije kaž ličby, e-mejlowe a rozsyłanske adresy zapřijećWobsahuje telefonowe čisła a e-mejlowe adresy
@@ -1956,8 +1938,6 @@
Kartu zhašeć
- Chceće woprawdźe tutu kreditnu kartu zhašeć?
-
Kartu zhašeć?Zhašeć
@@ -1971,24 +1951,15 @@
Składowane karty
-
- Prošu zapodajće płaćiwe čisło kreditneje karty
-
Zapodajće płaćiwe kartowe čisło
-
- Prošu wupjelńće tute poloPřidajće mjenoZa zwobraznjenje wašich składowanych kartow wotewrěć
- Waše kreditne karty zawěsćić
-
Zawěsćće swoje składowane płaćenske metody
- Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym kreditnym kartam zadźěwał, jeli něchtó druhi waš grat ma.
-
Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym płácenskim metodam zadźěwał, jeli něchtó druhi waš grat ma.Nětko konfigurować
@@ -1997,9 +1968,6 @@
Wotewriće swój grat
-
- Blokowanje zběhnyć, zo bychu so składowane informacije kreditneje karty wužiwali
-
Wotewrěć, zo byšće składowane płaćenske metody wužiwał
@@ -2008,12 +1976,6 @@
Adresu wobdźěłaćAdresy rjadować
-
- Předmjeno
-
- Druhe předmjeno
-
- Swójbne mjenoMjeno
@@ -2039,8 +2001,6 @@
Adresu zhašeć
-
- Chceće woprawdźe tutu adresu zhašeć?Tutu adresu zhašeć?
@@ -2140,49 +2100,29 @@
ZhašećWobdźěłać
-
- Chceće woprawdźe tute přizjewjenje zhašeć?Chceće woprawdźe tute hesło zhašeć?ZhašećPřetorhnyć
-
- Přizjewjenske nastajenjaHesłowe nastajenja
-
- Wobdźěłujomne tekstowe polo za webadresu přizjewjenja.Wobdźěłujomne tekstowe polo za adresu websydła.
-
- Wobdźěłujomne tekstowe polo za wužiwarske mjeno přizjewjenja.Wobdźěłujomne tekstowe polo za wužiwarske mjeno.
- Wobdźěłujomne tekstowe polo za hesło přizjewjenja.
-
Wobdźěłujomne tekstowe polo za hesło.
-
- Změny přizjewjenja składowaćZměny składować.
-
- WobdźěłaćHesło wobdźěłać
-
- Nowe přizjewjenje přidaćHesło přidać
-
- Hesło trěbneHesło zapodać
- Wužiwarske mjeno trěbne
-
Wužiwarske mjeno zapodaćHostmjeno trěbne
@@ -2590,6 +2530,9 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
Stronu Přełožki začinić
+
+ Někotre nastajenja na chwilu k dispoziciji njejsu.
+
Přełožki
@@ -2613,6 +2556,9 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
Wubjerće rěč, zo byšće nastajeni „přeco přełožić“ a „ženje njepřełožić“ rjadował.
+
+ Rěče njedachu so začitać. Prošu spytajće pozdźišo hišće raz.
+
Přełožk poskićić (standard)
@@ -2636,6 +2582,8 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
%1$s wotstronić
+
+ Sydła njedachu so začitać. Prošu spytajće pozdźišo hišće raz.%1$s zhašeć?
@@ -2713,13 +2661,18 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
Wróćo nawigěrować
+
+ Debug drawer wočinić
+
Rajtarkowe nastrojeLičba rajtarkow
- Aktiwny
+ Aktiwny
+
+ AktiwnyNjeaktiwny
@@ -2730,6 +2683,16 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
Nastroj za wutworjenje rajtarkowLičba rajtarkow, kotrež so maja wutworić
+
+ Tekstowe polo je prózdne
+
+ Prošu zapodajće jenož pozitiwne cyłe ličby
+
+ Prošu zapodajće ličbu, kotraž je wjetša hač nula
+
+ Maksimalna ličba rajtarkow (%1$s), kotrež dadźa so w jednej operaciji generěrować, je překročenaAktiwnym rajtarkam přidać
@@ -2746,11 +2709,11 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
Zdźělenka priwatnosće
- Wotpósłać
+ Wotpósłać
- Začinić
+ Začinić
- Dźakujemy so za waš komentar!
+ Dźakujemy so za waš komentar!Jara spokojny
@@ -2762,6 +2725,14 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk
Jara njespokojny
+
+
+ Naprašowanje wočinić
+
+ Naprašowanje začinić
+
+ Začinić
+
Přizjewjenja
diff --git a/mobile/android/fenix/app/src/main/res/values-hu/strings.xml b/mobile/android/fenix/app/src/main/res/values-hu/strings.xml
index 4131faf3bb..efffda262e 100644
--- a/mobile/android/fenix/app/src/main/res/values-hu/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-hu/strings.xml
@@ -48,12 +48,20 @@
- Nemrég mentett
+ Nemrég mentett
- Összes mentett könyvjelző megjelenítése
+ Összes mentett könyvjelző megjelenítése
- Eltávolítás
+ Eltávolítás
+
+
+
+ Könyvjelzők
+
+ Összes könyvjelző megjelenítése
+
+ EltávolításA %1$s a Mozilla terméke.
@@ -191,6 +199,10 @@
KiegészítőkKiegészítők
+
+ Kiegészítők kezelése
+
+ További kiegészítők felfedezéseFiókinformáció
@@ -209,6 +221,8 @@
Megnyitás szokásos laponKezdőképernyőhöz adás
+
+ Hozzáadás a kezdőképernyőhöz…Telepítés
@@ -220,9 +234,13 @@
Oldal fordítása
+ Mentés gyűjteménybe…
+
Gyűjteménybe mentésMegosztás
+
+ Megosztás…Megnyitás ezzel: %1$s
@@ -277,6 +295,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Mentés
+
+ Oldal könyvjelzőzése
+
+ Könyvjelző szerkesztése
+
+ Mentés PDF-ként…
+
+ Olvasó nézetet bekapcsolása
+
+ Olvasó nézet kikapcsolása
+
+ Oldal fordítása…
+
+ Lefordítva erre: %1$s
+
+ Nyomtatás…
+
Itt nincsenek kiegészítők
@@ -582,6 +618,10 @@
Újracsatlakozás a szinkronizálás folytatásáhozNyelv
+
+ Fordítás
+
+ FordításokAdatküldések
@@ -689,7 +729,9 @@
Ugrás vissza
- Friss könyvjelzők
+ Friss könyvjelzők
+
+ KönyvjelzőkNemrég felkeresett
@@ -829,6 +871,14 @@
Lap innen: %s
+
+
+ %1$s lap bezárva: %2$d
+
+ Nemrég bezárt lapok megtekintése
+
Kivételek
@@ -2529,6 +2579,8 @@
Most nemEredeti megjelenítése
+
+ Eredeti, lefordítatlan oldal betöltveKész
@@ -2712,13 +2764,18 @@
Navigálás visszafelé
+
+ Hibakereső fiók megnyitása
+
LapeszközökLapok száma
- Aktív
+ Aktív
+
+ AktívInaktív
diff --git a/mobile/android/fenix/app/src/main/res/values-hy-rAM/strings.xml b/mobile/android/fenix/app/src/main/res/values-hy-rAM/strings.xml
index 4b5ebebaef..7ae4420a7b 100644
--- a/mobile/android/fenix/app/src/main/res/values-hy-rAM/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-hy-rAM/strings.xml
@@ -24,7 +24,7 @@
Որոնել ներդիրներ
- Մուտքագրեք որոնվող բառը
+ Մուտքագրեք որոնման եզրույթներՁեր բաց ներդիրները կցուցադրվեն այստեղ:
@@ -199,6 +199,10 @@
ՀավելումներԸնդլայնումներ
+
+ Կառավարել ընդլայնումները
+
+ Բացահայտեք ավելի շատ ընդլայնումներՀաշվի տվյալներ
@@ -217,6 +221,8 @@
Բացել կանոնավոր ներդիրումԱվելացնել Տնային էկրանին
+
+ Ավելացնել Տուն էկրանին…Տեղադրել
@@ -229,9 +235,13 @@
Թարգմանել էջը
+ Պահել հավաքածույում…
+
Պահպանել հավաքածուումՏարածել
+
+ Համօգտագործել…Բացել %1$s-ում
@@ -284,6 +294,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Պահպանել
+
+ Էջանշել այս էջը
+
+ Խմբագրել Էջանիշը
+
+ Պահել որպես PDF…
+
+ Միացնել Ընթերցելու եղանակը
+
+ Անջատել Ընթերցելու եղանակը
+
+ Թարգմանել էջը…
+
+ Թարգմանված է %1$s
+
+ Տպել…
+
Այստեղ ընդլայնումներ չկան
@@ -379,8 +407,6 @@
Firefox֊ի գաղտնիության ծանուցում
-
- Իմացեք ավելին մեր գաղտնիության ծանուցման մեջՄենք սիրում ենք ձեզ ապահով պահել
- Թարգմանություն
+ Թարգմանություն
+
+ ԹարգմանություններՏվյալների ընտրություն
@@ -662,10 +690,6 @@
ՊահանջվածԿամընտրական
-
- Կարդալ և փոխել վեբկայքի տվյալները
-
- Ջնջել վեբկայքըԹույլատրել բոլոր կայքերի համար
@@ -790,8 +814,6 @@
ՊատմությունԷջանիշեր
-
- ՄուտքանուններԳաղտնաբառեր
@@ -818,8 +840,6 @@
and the third is the device model. -->
%1$s-ը %2$s %3$s-ում
-
- Բանկային քարտերՎճարամիջոցներ
@@ -835,6 +855,14 @@
Ներդիր %s-ից
+
+
+ %1$s-ի փակված ներդիրները՝ %2$d
+
+ Դիտել վերջերս փակված ներդիրները
+
Բացառություններ
@@ -869,7 +897,7 @@
- firefox.com/pair-ում ցուցադրված QR կոդը]]>
+ firefox.com/pair-ում ցուցադրված QR կոդը]]>
@@ -1022,7 +1050,7 @@
Չեղարկել
- Փոփոխությունները գործադրելու համար դուրս է գալիս հավելվածից…
+ Փոփոխությունները կիրառելու համար լքում է հավելվածը…
@@ -1091,7 +1119,7 @@
- Մուտքագրեք որոնվող բառը
+ Մուտքագրեք որոնման եզրույթներՋնջել պատմությունը
@@ -1134,7 +1162,7 @@
- Ներողություն. %1$s-ը չի կարող բեռնել այդ էջը:
+ Ներողություն: %1$s-ը չի կարող բեռնել այդ էջը:Ուղարկել վթարի զեկույցը Mozilla-ին
@@ -1210,7 +1238,7 @@
ՀԵՏԱՐԿԵԼ
- Մուտքագրեք որոնվող բառը
+ Մուտքագրեք որոնման եզրույթներ
@@ -1266,7 +1294,7 @@
Անջ.
- Ստանդարտ
+ ՍովորականԽիստ
@@ -1390,7 +1418,7 @@
Հասկացա
- Հնարավոր չէ տարածել այս հավելվածին
+ Չստացվեց տարածել այս հավելվածինՈւղարկել սարքի
@@ -1586,7 +1614,7 @@
https://firefox.com/pair]]>
- Պատրաստ է սկանավորել
+ Պատրաստ է սկանավորմանՄուտք գործել Ձեր տեսախցիկով
@@ -1614,7 +1642,7 @@
Իմանալ ավելին
- Ստանդարտ (սկզբնադիր)
+ Սովորական (սկզբնադիր)Էջերը նորմալ կբեռնվեն, բայց արգելափակվելու են ավելի քիչ հետագծիչներ:
@@ -1760,13 +1788,9 @@
Հեշտությամբ կարող եք ավելացնել այս կայքը ձեր հեռախոսի Տնային էկրանին՝ ակնթարթորեն մատչելու և արագ դիտարկելու համար:
-
- Մուտքանուններ և գաղտնաբառերԳաղտնաբառեր
- Պահպանել մուտքանունները և գաղտնաբառերը
-
Պահել գաղտնաբառերըՀարցնել պահպանելիս
@@ -1781,46 +1805,27 @@
Լրացրեք օգտանունները և գաղտնաբառերը Ձեր սարքի այլ հավելվածներում:
-
- Հավելել մուտքանուն
-
Հավելել գաղտնաբառ
-
- Համաժամեցնել մուտքանուններըՀամաժամեցնել գաղտնաբառերը
-
- Համաժամեցնել մուտքանունները սարքերի միջևՀամաժամեցնել գաղտնաբառերը սարքերի միջև
-
- Պահպանված մուտքանուններՊահված գաղտնաբառեր
- %s-ի հետ ձեր պահպանած կամ համաժամեցրած մուտքանունները կցուցադրվեն այստեղ:
-
Այն գաղտնաբառերը, որոնք դուք պահում կամ համաժամացնում եք %s-ի հետ, կցուցադրվեն այստեղ: Ձեր պահած բոլոր գաղտնաբառերը գաղտնագրված են:
-
- Իմանալ ավելին համաժամեցման մասին:Իմանալ ավելին Սինքի մասինԲացառություններ
-
- Մուտքանունները և գաղտնաբառերը, որոնք չեն պահպանվել, կցուցադրվեն այստեղ:%s-ը չի պահի այստեղ թվարկված կայքերի գաղտնաբառերը:
-
- Մուտքանունները և գաղտնաբառերը չեն պահպանվի այս կայքերի համար:%s-ը չի պահի այս կայքերի գաղտնաբառերը:Ջնջել բոլոր բացառությունները
-
- Որոնել մուտքանուններՈրոնել գաղտնաբառեր
@@ -1850,17 +1855,11 @@
Ցուցադրել գաղտնաբառըԹաքցնել գաղտնաբառը
-
- Ապակողպեք՝ դիտելու համար պահպանված մուտքանուններըԱպակողպեք՝ դիտելու համար պահված գաղտնաբառերը
- Անվտանգ դարձրեք ձեր մուտքանունները և գաղտնաբառերը
-
Անվտանգ դարձրեք ձեր պահված գաղտնաբառերը
- Ստեղծեք սարքի կողպեքի նմուշ, PIN կամ գաղտնաբառ՝ ձեր պահպանված մուտքանունները և գաղտնաբառերը մուտք գործելուց պաշտպանելու համար, եթե ձեր սարքը ուրիշի ձեռքն ընկնի:
-
Տեղակայեք սարքի կողպման նախշ, PIN կամ գաղտնաբառ՝ պաշտպանելու պահված գաղտնաբառերն այն դեպքում, եթե որևէ մեկը ևս մուտք ունենա Ձեր սարքին:Հետո
@@ -1878,51 +1877,35 @@
Անվան (Ա-Ֆ)Վերջին օգտագործվածը
-
- Տեսակավորել մուտագրումների ցանկըՏեսակավորել գաղտնաբառերի ցանկը
- Ինքնալցում
+ ԻնքնալրացումՀասցեներ
-
- Բանկային քարտերՎճարամիջոցներ
- Պահել և ինքնալրացնել քարտերը
-
Պահել և լրացնել վճարամիջոցները
-
- Տվյալները գաղտնագրված են%s-ը գաղտնագրում է ձեր պահած բոլոր վճարամիջոցներըՀամաժամեցնել քարտերը սարքերի միջևՀամաժամեցնել քարտերը
-
- Ավելացնել բանկային քարտՀավելել քարտ
-
- Կառավարել պահված քարտերըԿառավարել քարտերըԱվելացնել հասցեԿառավարեք հասցեները
-
- Պահել և ինքնալրացնել քարտերըՊահել և լրացնել հասցեները
-
- Ներառել տեղեկություններ, ինչպիսիք են համարները, էլ.փոստը և առաքման հասցեներըՆերառում է հեռախոսահամարներ և էլ. փոստի հասցեներ
@@ -1946,8 +1929,6 @@
Ջնջել քարտը
- Համոզվա՞ծ եք, որ ցանկանում եք ջնջել այս բանկային քարտը:
-
Ջնջե՞լ քարտըՋնջել
@@ -1961,24 +1942,15 @@
Պահպանված քարտեր
-
- Մուտքագրեք բանկային վավեր քարտի համար
-
Մուտքագրեք ճիշտ քարտի համար
-
- Լրացրեք այս դաշտըՀավելել անունԱպակողպեք՝ դիտելու համար պահպանված քարտերը
- Անվտանգ դարձրեք ձեր բանկային քարտերը
-
Անվտանգ դարձրեք ձեր պահած վճարամիջոցները
- Տեղակայեք սարքի կողպման նախշ, PIN կամ գաղտնաբառ՝ պաշտպանելու պահված բանկային քարտերը այն դեպքում, եթե որևէ մեկը ևս մուտք ունի Ձեր սարքին:
-
Տեղակայեք սարքի կողպման նախշ, PIN կամ գաղտնաբառ՝ պաշտպանելու ձեր քարտերն այն դեպքում, եթե որևէ մեկը ևս մուտք ունենա Ձեր սարքին:Տեղակայել հիմա
@@ -1986,8 +1958,6 @@
Ավելի ուշԱպակողպեք ձեր սարքը
-
- Ապակողպեք՝ օգտագործելու համար բանկային քարտերի պահված տեղեկություններըԱպակողպեք՝ պահված վճարամիջոցն օգտագործելու համար
@@ -1997,12 +1967,6 @@
Խմբագրել հասցենԿառավարեք հասցեները
-
- Անուն
-
- Հայրանուն
-
- ԱզգանունԱնուն
@@ -2028,8 +1992,6 @@
Ջնջել հասցեն
- Ջնջե՞լ այս հասցեն:
-
Ջնջե՞լ այս հասցեն:Ջնջել
@@ -2126,49 +2088,29 @@
ՋնջելԽմբագրել
-
- Համոզվա՞ծ եք, որ ցանկանում եք ջնջել այս մուտքանունը:Համոզվա՞ծ եք, որ ցանկանում եք ջնջել այս գաղտնաբառը:ՋնջելՉեղարկել
-
- Մուտքի ընտրանքներԳաղտնաբառի ընտրանքներ
-
- Խմբագրելի տեքստի դաշտը մուտքի վեբ հասցեի համար:Խմբագրելի տեքստի դաշտ կայքի հասցեի համար:
-
- Խմբագրելի տեքստի դաշտը մուտք գործողի համար:Խմբագրելի տեքստի դաշտ օգտվողի անվան համար:
- Խմբագրելի տեքստի դաշտը մուտքի գաղտնաբառի համար:
-
Խմբագրելի տեքստի դաշտ գաղտնաբառի համար:
-
- Պահպանել փոփոխությունները մուտքագրման համար:Պահել փոփոխությունները:
-
- ԽմբագրելԽմբագրել գաղտնաբառը
-
- Հավելել նոր մուտքանունՀավելել գաղտնաբառ
-
- Գաղտնաբառ է պահանջվումՄուտքագրեք գաղտնաբառ
- Օգտվողի անունը պարտադիր է
-
Մուտքագրեք օգտվողի անունըՀոսթի անունը պարտադիր է
@@ -2576,6 +2518,9 @@
Փակել թարգմանությունների թերթիկը
+
+ Որոշ կարգավորումներ ժամանակավորապես անհասանելի են։
+
Թարգմանություններ
@@ -2598,6 +2543,9 @@
Ընտրեք լեզուն՝ «միշտ թարգմանել» և «երբեք չթարգմանել» նախապատվությունները կառավարելու համար:
+
+ Չստացվեց բեռնել լեզուները։ Խնդրում ենք կրկին ստուգել՝ ավելի ուշ։
+
Թարգմանելու առաջարկ (սկզբնադիր)
@@ -2620,6 +2568,8 @@
Հեռացնել %1$s-ը
+
+ Չստացվեց բեռնել կայքերը։ Խնդրում ենք կրկին ստուգել՝ ավելի ուշ։Ջնջե՞լ %1$s-ը:
@@ -2697,13 +2647,18 @@
Նավարկել հետ
+
+ Բացել վրիպազերծման գզրոցը
+
Ներդիրի գործիքներՆերդիրների քանակը
- Ակտիվ
+ Ակտիվ
+
+ ԱկտիվԱնգործուն
@@ -2714,6 +2669,16 @@
Ներդիրների ստեղծման գործիքՆերդիրների քանակ ստեղծելու համար
+
+ Տեքստային դաշտը դատարկ է
+
+ Խնդրում ենք մուտքագրել միայն դրական ամբողջ թվեր
+
+ Խնդրում ենք մուտքագրել զրոյից մեծ թիվ
+
+ Գերազանցվել է ներդիրների առավելագույն քանակը (%1$s), որոնք կարող են ստեղծվել մեկ գործողության ընթացքումՀավելել ակտիվ ներդիրներին
@@ -2730,11 +2695,11 @@
Գաղտնիության դրույթներ
- Ուղարկել
+ Ուղարկել
- Փակել
+ Փակել
- Շնորհակալությո՜ւն Ձեր արձագանքի համար:
+ Շնորհակալությո՜ւն Ձեր արձագանքի համար:Շատ գոհ
@@ -2746,6 +2711,14 @@
Շատ դժգոհ
+
+
+ Բացել հարցումը
+
+ Փակել հարցումը
+
+ Փակել
+
Մուտքանուններ
diff --git a/mobile/android/fenix/app/src/main/res/values-ia/strings.xml b/mobile/android/fenix/app/src/main/res/values-ia/strings.xml
index 8aed75c096..91b8cce44c 100644
--- a/mobile/android/fenix/app/src/main/res/values-ia/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-ia/strings.xml
@@ -202,6 +202,10 @@
AdditivosExtensiones
+
+ Gerer extensiones
+
+ Discoperir altere extensionesInformationes del conto
@@ -220,6 +224,8 @@
Aperir in un scheda regularAdder al pagina initial
+
+ Adder al pagina initial…Installar
@@ -231,9 +237,13 @@
Traducer le pagina
+ Salvar al collection…
+
Salvar al collectionCompartir
+
+ Compartir…Aperir in %1$s
@@ -287,6 +297,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Salvar
+
+ Adder un marcapaginas pro iste pagina
+
+ Rediger marcapagina
+
+ Salvar como PDF…
+
+ Activar modo lectura
+
+ Disactivar modo lectura
+
+ Traducer le pagina…
+
+ Traducite in %1$s
+
+ Imprimer…
+
Nulle extensiones hic
@@ -385,8 +413,6 @@
Aviso de confidentialitate de Firefox
-
- Lege nostre aviso de confidentialitateA nos place mantener te securLingua
- Traduction
+ Traduction
+
+ TraductionesSelectiones de datos
@@ -669,10 +697,6 @@
NecessariOptional
-
- Leger e cambiar datos del sito web
-
- Deler le sito webPermitter a tote le sitos
@@ -801,8 +825,6 @@
ChronologiaMarcapaginas
-
- CredentialesContrasignos
@@ -829,8 +851,6 @@
and the third is the device model. -->
%1$s sur %2$s %3$s
-
- Cartas de creditoMethodos de pagamento
@@ -848,6 +868,14 @@
Scheda veniente de %s
+
+
+ Schedas de %1$s clause: %2$d
+
+ Vider schedas recentemente claudite
+
Exceptiones
@@ -1809,14 +1837,9 @@
Tu pote facilemente adder iste sito web al Pagina initial de tu apparato pro haber accesso instantanee e navigar plus veloce con un experientia simile al app.
-
- Credentiales e contrasignos
-Contrasignos
- Salvar credentiales e contrasignos
-
Salvar contrasignosDemandar pro salvar
@@ -1833,46 +1856,27 @@
Plenar nomines de usator e contrasignos in altere apps sur tu apparato.
-
- Adder credentiales
-
Adder contrasigno
-
- Synchronisar credentialesSynchronisar contrasignos
-
- Synchronisar credentiales inter le apparatosSynchronisar contrasignos inter apparatos
-
- Credentiales salvateContrasignos salvate
- Le credentiales que tu salva o synchronisa a in %s apparera hic.
-
Le contrasignos que tu salva o synchronisa in %s sera listate ci. Tote le contrasignos que tu salva es cryptate.
-
- Apprender plus re Sync.Apprender plus re le synchronisationExceptiones
-
- Credentiales e contrasignos que non es salvate essera monstrate hic.%s non salvara le password pro le sitos ci listate.
-
- Credentiales e contrasignos non sera salvate pro iste sitos.%s non salvara le contrasignos pro iste sitos.Deler tote le exceptiones
-
- Cercar credentialesCercar contrasignos
@@ -1901,17 +1905,11 @@
Monstrar contrasignoCelar contrasigno
-
- Disbloca pro vider tu credentiales salvateDisbloca pro vider tu contrasignos salvate
- Assecurar tu credentiales e contrasignos
-
Protege tu contrasignos salvate
- Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu credentiales e contrasignos salvate de esser accedite, si alcuno altere ha tu apparato.
-
Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu contrasignos de esser accedite, si alcuno altere ha tu apparato.Plus tarde
@@ -1929,9 +1927,6 @@
Ultimemente usate
-
- Ordinar menu de credentiales
-
Ordinar le menu del contrasignos
@@ -1940,16 +1935,10 @@
AutoplenarAdresses
-
- Cartas de creditoMethodos de pagamento
- Gerer le cartas salvate
-
Salvar e compilar methodos de pagamento automaticamente
-
- Datos es cryptate%s crypta tote tu methodos de pagamento salvate
@@ -1957,12 +1946,8 @@
Synchronisar cartas
-
- Adde un carta de creditoAdder carta
-
- Gerer le cartas salvateGerer le cartas
@@ -1970,13 +1955,8 @@
Gerer adresses
-
- Salvar e autoplenar adresses
-
Salvar e compilar automaticamente adresses
-
- Includer informationes como numeros, email e adresses de expeditionInclude numeros de telephono e adresses email
@@ -2000,8 +1980,6 @@
Deler carta
- Desira tu vermente deler iste carta de credito?
-
Deler carta?Deler
@@ -2015,24 +1993,15 @@
Cartas salvate
-
- Insere un numero valide de carta de credito
-
Insere un numero de carta valide
-
- Completa iste campoAdde un nomineDisbloca pro vider tu cartas salvate
- Protege tu carta de credito
-
Protege tu methodo de pagamento salvate
- Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu cartas de credito de esser accedite, si alcuno altere ha tu apparato.
-
Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu methodos de pagamento salvate de esser accedite, si alcun altere ha tu apparato.Implementar ora
@@ -2041,9 +2010,6 @@
Disbloca tu apparato
-
- Disbloca pro usar le informationes de carta de credito immagazinate
-
Disblocar pro usar le methodo de pagamento salvate
@@ -2052,12 +2018,6 @@
Modificar le adresseGerer addresses
-
- Prenomine
-
- Nomine intermedie
-
- Nomine de familiaNomine
@@ -2083,8 +2043,6 @@
Deler adresses
-
- Desira tu vermente deler iste adresses?Deler iste adresses?
@@ -2185,50 +2143,30 @@
DelerRediger
-
- Desira tu vermente deler iste credentiales?Desira tu vermente deler iste contrasigno?DelerCancellar
-
- Optiones de apertura de sessionOptiones de contrasigno
-
- Le campo de texto redigibile pro le adresse web del credentiales.Le campo de texto redigibile pro le adresse del sito web.
-
- Le campo de texto redigibile pro le nomine de usator del accesso.Le campo de texto redigibile pro le nomine de usator.
- Le campo de texto redigibile pro le contrasigno del credentiales.
-
Le campo de texto redigibile pro le contrasigno.
-
- Salvar cambiamentos a credentiales.Salvar le cambiamentos.
-
- RedigerModificar le contrasigno
-
- Adder nove credentialAdder contrasigno
-
- Contrasigno requiriteInsere un contrasigno
- Nomine de usator necesse.
-
Insere un nomine de usatorNomine de servitor necesse.
@@ -2636,6 +2574,9 @@
Eliger folio de traductiones
+
+ Alcun parametros es temporarimente indisponibile.
+
Traduction
@@ -2658,6 +2599,9 @@
Elige un lingua pro gerer le preferentias “sempre traducer” e “jammais traducer”.
+
+ Impossibile cargar le linguas. Re-controla plus tarde.
+
Offerer le traduction (predefinite)
@@ -2680,6 +2624,8 @@
Remover %1$s
+
+ Impossibile cargar sitos. Retenta plus tarde.Deler %1$s?
@@ -2757,13 +2703,18 @@
Naviga a retro
+
+ Aperir tiratorio de depuration
+
Numero de schedasNumero de schedas
- Active
+ Active
+
+ ActiveInactive
@@ -2774,6 +2725,16 @@
Utensile pro creation de schedasNumero de schedas a crear
+
+ Le campo de texto es vacue
+
+ Solo insere numeros integre positive
+
+ Insere un numero major que zero
+
+ Excedite le maxime numero de schedas (%1$s) que pote esser generate in un operationAdder a schedas active
@@ -2790,11 +2751,11 @@
Aviso de confidentialitate
- Inviar
+ Inviar
- Clauder
+ Clauder
- Gratias pro tu commentario!
+ Gratias pro tu commentario!Absolutemente satisfacite
@@ -2806,6 +2767,14 @@
Absolutemente non satisfacite
+
+
+ Aperir sondage
+
+ Clauder le questionario
+
+ Clauder
+
Authenticationes
diff --git a/mobile/android/fenix/app/src/main/res/values-is/strings.xml b/mobile/android/fenix/app/src/main/res/values-is/strings.xml
index 2cbbea4ff7..8c5d707a9c 100644
--- a/mobile/android/fenix/app/src/main/res/values-is/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-is/strings.xml
@@ -198,6 +198,10 @@
ViðbæturForritsaukar
+
+ Sýsla með forritsauka
+
+ Uppgötvaðu fleiri forritsaukaUpplýsingar um reikning
@@ -217,6 +221,8 @@
Opna í venjulegum flipaBæta við á ræsisíðu
+
+ Bæta við á upphafsskjá…Setja upp
@@ -228,9 +234,13 @@
Þýða síðu
+ Vista í safn…
+
Vista í safnDeila
+
+ Deila…Opna með %1$s
@@ -284,6 +294,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Vista
+
+ Setja síðu í bókamerki
+
+ Breyta bókamerki
+
+ Vista sem PDF…
+
+ Kveikja á lesham
+
+ Slökkva á lesham
+
+ Þýða síðu…
+
+ Þýtt á %1$s
+
+ Prenta…
+
Engir forritsaukar hér
@@ -380,8 +408,6 @@
Meðferð persónuupplýsinga í Firefox
-
- Sjáðu nánar í persónuverndaryfirlýsingu okkarVið fáum kikk út úr því að halda þér öruggumTungumál
- Þýðing
+ Þýðing
+
+ ÞýðingarGagnamöguleikar
@@ -663,10 +691,6 @@
NauðsynlegtValkvætt
-
- Lesa og breyta vefsíðugögnum
-
- Eyða vefsvæðiLeyfa fyrir öll vefsvæði
@@ -792,8 +816,6 @@
FerilBókamerki
-
- InnskráningarLykilorð
@@ -820,8 +842,6 @@
and the third is the device model. -->
%1$s á %2$s %3$s
-
- GreiðslukortGreiðslumátar
@@ -837,6 +857,14 @@
Flipi frá %s
+
+
+ %1$s flipum lokað: %2$d
+
+ Skoða nýjustu flipa sem var lokað
+
Undanþágur
@@ -1758,13 +1786,9 @@
Þú getur á auðveldan hátt bætt þessu vefsvæði á upphafsskjáinn þinn fyrir auðveldara aðgengi og hraðara vafur.
-
- Innskráning og lykilorðLykilorð
- Vista innskráningu og lykilorð
-
Vista lykilorðBiðja um að vista
@@ -1779,48 +1803,30 @@
Sjálfvirk útfylling í öðrum forritumFylltu út notendanöfn og lykilorð í öðrum forritum á tækinu þínu.
-
- Bæta við innskráninguBæta við lykilorði
-
- Samstilla innskráningarSamstilla lykilorð
-
- Samstilla innskráningar milli tækjaSamstilla lykilorð milli tækja
-
- Vistaðar innskráningarVistuð lykilorð
-
- Innskráningarnar sem þú vistar eða samstillir við %s birtast hér.Lykilorðin sem þú vistar eða samstillir við %s verða skráð hér. Öll lykilorð sem þú vistar eru dulrituð.
-
- Læra meira um samstillingu.Frekari upplýsingar um samstillinguUndanþágur
-
- Innskráningar og lykilorð sem ekki eru vistuð sjást hér.%s mun ekki vista lykilorð fyrir vefsvæði sem skráð eru hér.
-
- Innskráningar og lykilorð verða ekki vistuð fyrir þessi vefsvæði.%s mun ekki vista lykilorð fyrir þessi vefsvæði.Eyða öllum undantekningum
-
- Leita að innskráninguLeita að lykilorðum
@@ -1849,17 +1855,11 @@
Sýna lykilorðFela lykilorð
-
- Aflæstu til að skoða vistaðar innskráningarAflæstu til að skoða vistuð lykilorð
- Verndaðu innskráningar þínar og lykilorð
-
Tryggðu öryggi vistuðu lykilorðanna þinna
- Settu upp læsimynstur, PIN eða lykilorð til að vernda vistaðar innskráningar og lykilorð ef ske kynni að einhver annar komist yfir tækið þitt.
-
Settu upp læsimynstur, PIN-númer eða lykilorð til að vernda vistuðu lykilorðin þín ef ske kynni að einhver annar komist yfir tækið þitt.Síðar
@@ -1877,8 +1877,6 @@
Nafn (A-Z)Síðast notað
-
- Raða innskráningarvalmyndinniRaða lykilorðavalmynd
@@ -1888,40 +1886,26 @@
Sjálfvirk útfyllingTölvupóstföng
-
- GreiðslukortGreiðslumátar
- Vista og fylla sjálfkrafa út í greiðslukort
-
Vista og fylla út greiðslumáta
-
- Gögn eru dulrituð%s dulritar alla greiðslumáta sem þú vistarSamstilla greiðslukort milli tækjaSamstilla kort
-
- Bæta við greiðslukortiBæta við korti
-
- Sýsla með vistuð greiðslukortSýsla með greiðslukortBæta við tölvupóstfangiSýsla með tölvupóstföng
-
- Vista og fylla sjálfkrafa út heimilisföngVista og fylla út í heimilisföng
-
- Láta upplýsingar eins og símanúmer, tölvupóstföng og heimilisföng fylgja meðÞar með talin símanúmer og tölvupóstföng
@@ -1946,8 +1930,6 @@
Eyða korti
- Ertu viss um að þú viljir eyða þessu greiðslukorti?
-
Eyða korti?Eyða
@@ -1959,23 +1941,15 @@
Hætta viðVistuð greiðslukort
-
- Settu inn gilt kortanúmerSettu inn gilt kortanúmer
-
- Fylltu út í þennan reitBættu við nafniAflæsa til að skoða vistuð greiðslukort
- Haltu kreditkortunum þínum öruggum
-
Tryggðu öryggi vistuðu greiðslumátanna þinna
- Settu upp læsimynstur, PIN-númer eða lykilorð til að vernda vistuðu greiðslukortin þín ef ske kynni að einhver annar komist yfir tækið þitt.
-
Settu upp læsimynstur, PIN-númer eða lykilorð til að vernda vistuðu greiðslumátana þína ef ske kynni að einhver annar komist yfir tækið þitt.Setja upp núna
@@ -1983,8 +1957,6 @@
SíðarAflæstu tækinu þínu
-
- Aflæstu til að nota geymdar kreditkortaupplýsingarAflæstu til að nota vistaða greiðslumáta
@@ -1994,12 +1966,6 @@
Breyt tölvupóstfangiSýsla með tölvupóstföng
-
- Skírnarnafn
-
- Millinafn
-
- EftirnafnNafn
@@ -2025,8 +1991,6 @@
Eyða heimilisfangi
-
- Ertu viss um að þú viljir eyða þessu póstfangi?Eyða þessu heimilisfangi?
@@ -2126,49 +2090,29 @@
EyðaBreyta
-
- Ertu viss um að þú viljir eyða þessari innskráningu?Ertu viss um að þú viljir eyða þessu lykilorði?EyðaHætta við
-
- InnskráningarvalkostirValkostir lykilorðs
-
- Breytilegi textareiturinn fyrir veffang þessarar innskráningarinnar.Breytanlegi textareiturinn fyrir vistfang vefsvæðisins.
-
- Breytilegi textareiturinn fyrir notandanafn innskráningarinnar.Breytanlegi textareiturinn fyrir notandanafnið.
- Breytilegi textareiturinn fyrir lykilorð innskráningarinnar.
-
Breytanlegi textareiturinn fyrir lykilorðið.
-
- Vista breytingar á innskráningu.Vista breytingar.
-
- BreytaBreyta lykilorði
-
- Bæta við nýrri innskráninguBæta við lykilorði
-
- Lykilorðs krafistSettu inn lykilorð
- Notandanafn er nauðsynlegt
-
Settu inn notandanafnHýsingarheiti er nauðsynlegt
@@ -2577,6 +2521,9 @@
Loka þýðingarblaði
+
+ Sumar stillingar eru ekki aðgengilegar eins og stendur.
+
Þýðingar
@@ -2599,6 +2546,9 @@
Veldu tungumál til að stjórna stillingum á „alltaf þýða“ og „aldrei þýða“.
+
+ Ekki tókst að hlaða tungumálum. Athugaðu aftur síðar.
+
Bjóðast til að þýða (sjálfgefið)
@@ -2622,6 +2572,8 @@
Fjarlægja %1$s
+
+ Ekki tókst að hlaðið inn vefsvæðum. Athugaðu aftur síðar.Eyða %1$s?
@@ -2699,13 +2651,18 @@
Fara til baka
+
+ Opna villuleitarspjald
+
FlipaverkfæriFjöldi flipa
- Virkir
+ Virkir
+
+ VirktÓvirkir
@@ -2716,6 +2673,16 @@
Verkfæri til að búa til flipaFjöldi flipa sem á að búa til
+
+ Textareiturinn er tómur
+
+ Settu aðeins inn jákvæðar heiltölur
+
+ Settu inn tölu sem er stærri en núll
+
+ Farið yfir hámarksfjölda flipa (%1$s) sem hægt er að búa til í einni aðgerðBæta við virka flipa
@@ -2732,11 +2699,11 @@
Meðferð persónuupplýsinga
- Senda inn
+ Senda inn
- Loka
+ Loka
- Takk fyrir álit þitt!
+ Takk fyrir álit þitt!Mjög ánægð/ur
@@ -2748,6 +2715,14 @@
Mjög óánægð/ur
+
+
+ Opna könnun
+
+ Loka könnun
+
+ Loka
+
Innskráningar
diff --git a/mobile/android/fenix/app/src/main/res/values-it/strings.xml b/mobile/android/fenix/app/src/main/res/values-it/strings.xml
index 36c423b38d..84154422c7 100644
--- a/mobile/android/fenix/app/src/main/res/values-it/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-it/strings.xml
@@ -201,6 +201,10 @@
Componenti aggiuntiviEstensioni
+
+ Gestisci estensioni
+
+ Scopri altre estensioniInformazioni sull’account
@@ -219,6 +223,8 @@
Apri in scheda normaleAgg. a schermata principale
+
+ Agg. a schermata principale…Installa
@@ -230,10 +236,14 @@
Traduci pagina
+ Salva in una raccolta…
+
Salva in una raccoltaCondividi
+
+ Condividi…Apri in %1$s
@@ -288,6 +298,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Salva
+
+ Aggiungi pagina ai segnalibri
+
+ Modifica segnalibro
+
+ Salva come PDF…
+
+ Attiva Modalità lettura
+
+ Disattiva Modalità lettura
+
+ Traduci pagina…
+
+ Tradotta in %1$s
+
+ Stampa…
+
Nessuna estensione disponibile
@@ -385,8 +413,6 @@
Informativa sulla privacy di Firefox
-
- Ulteriori informazioni nella nostra informativa sulla privacyCi piace mantenerti al sicuroLingua
- Traduzione
+ Traduzione
+
+ TraduzioniCondivisione dati
@@ -671,10 +699,6 @@
ObbligatorioFacoltativo
-
- Leggere e modificare i dati dei siti web
-
- Elimina sito webConsenti per tutti i siti
@@ -802,8 +826,6 @@
Segnalibri
-
- CredenzialiPassword
@@ -830,8 +852,6 @@
and the third is the device model. -->
%1$s su %2$s %3$s
-
- Carte di creditoMetodi di pagamento
@@ -848,6 +868,14 @@
Scheda da %s
+
+
+ Schede di %1$s chiuse: %2$d
+
+ Visualizza schede chiuse di recente
+
Eccezioni
@@ -1801,13 +1829,9 @@
È possibile aggiungere questo sito web alla schermata principale del dispositivo per accedervi più rapidamente, come se si trattasse di un’app.
-
- Credenziali e passwordPassword
- Salva credenziali e password
-
Salva passwordChiedi prima di salvare
@@ -1823,46 +1847,27 @@
Compila nomi utente e password nelle altre app del tuo dispositivo.
-
- Aggiungi credenziali
-
Aggiungi password
-
- Sincronizza le credenzialiSincronizza password
-
- Sincronizza credenziali tra dispositiviSincronizza le password tra i tuoi dispositivi
-
- Credenziali salvatePassword salvate
- Le credenziali salvate o sincronizzate in %s verranno visualizzate qui.
-
Le password salvate o sincronizzate con %s verranno visualizzate qui. Tutte le password salvate sono crittate.
-
- Ulteriori informazioni su Sync.Ulteriori informazioni sulla sincronizzazioneEccezioni
-
- Le credenziali e le password non salvate verranno mostrate qui.%s non salverà le password per i siti elencati qui.
-
- Le credenziali e le password non verranno salvate per questi siti.%s non salverà le password per questi siti.Elimina tutte le eccezioni
-
- Cerca credenzialiCerca nelle password
@@ -1891,17 +1896,11 @@
Mostra passwordNascondi password
-
- Sblocca per visualizzare le credenziali salvateSblocca per visualizzare le password salvate
- Proteggi le credenziali di accesso
-
Proteggi le password salvate
- Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare le tue credenziali.
-
Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare le password salvate.Più tardi
@@ -1919,8 +1918,6 @@
Nome (A-Z)Ultimo utilizzo
-
- Ordina il menu delle credenziali di accessoMenu per ordinare le password
@@ -1930,41 +1927,27 @@
Compilazione automaticaIndirizzi
-
- Carte di creditoMetodi di pagamento
- Salvare e compilare automaticamente le carte
-
Salva e compila i metodi di pagamento
-
- I dati sono crittati%s critta tutti i metodi di pagamento salvatiSincronizza le carte tra più dispositiviSincronizza carte di credito
-
- Aggiungi una carta di creditoAggiungi carta
-
- Gestione carte salvateGestisci carteAggiungi indirizzoGestione indirizzi
-
- Salvare e compilare automaticamente gli indirizziSalva e compila indirizzi
-
- Includere informazioni come numeri, email e indirizzi di spedizioneInclude numeri di telefono e indirizzi email
@@ -1989,8 +1972,6 @@
Elimina carta
- Eliminare questa carta di credito?
-
Eliminare la carta?Elimina
@@ -2004,24 +1985,15 @@
Carte salvate
-
- Inserire un numero di carta di credito valido
-
Inserisci un numero di carta valido
-
- Compilare questo campoAggiungi un nomeSblocca per visualizzare le carte di credito salvate
- Proteggi le tue carte di credito
-
Proteggi i metodi di pagamento salvati
- Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare le carte di credito salvate.
-
Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare i metodi di pagamento salvati.Imposta adesso
@@ -2030,9 +2002,6 @@
Sblocca il dispositivo
-
- Sblocca per utilizzare le informazioni delle carte di credito salvate
-
Sblocca per utilizzare i metodi di pagamento salvati
@@ -2041,12 +2010,6 @@
Modifica indirizzoGestione indirizzi
-
- Nome
-
- Secondo nome
-
- CognomeNome
@@ -2073,8 +2036,6 @@
Elimina indirizzo
-
- Eliminare questo indirizzo?Eliminare questo indirizzo?
@@ -2173,49 +2134,29 @@
EliminaModifica
-
- Rimuovere queste credenziali?Eliminare questa password?RimuoviAnnulla
-
- Opzioni credenzialiOpzioni password
-
- Il campo di testo modificabile per l’indirizzo web delle credenzialiIl campo di testo modificabile per l’indirizzo del sito web.
-
- Il campo di testo modificabile per il nome utente delle credenzialiIl campo di testo modificabile per il nome utente.
- Il campo di testo modificabile per la password delle credenziali
-
Il campo di testo modificabile per la password.
-
- Salva le modifiche alle credenziali.Salva modifiche.
-
- ModificaModifica password
-
- Aggiungi nuove credenzialiAggiungi password
-
- Password obbligatoriaInserisci una password
- Nome utente obbligatorio
-
Inserisci un nome utenteNome server obbligatorio
@@ -2627,6 +2568,9 @@
Chiudi il pannello per le traduzioni
+
+ Alcune impostazioni sono temporaneamente non disponibili.
+
Traduzioni
@@ -2649,6 +2593,9 @@
Seleziona una lingua per gestire le preferenze “Traduci sempre” e “Non tradurre mai“.
+
+ Impossibile caricare le lingue. Ricontrolla più tardi.
+
Proponi la traduzione (predefinita)
@@ -2672,6 +2619,8 @@
Rimuovi %1$s
+
+ Impossibile caricare i siti. Ricontrolla più tardi.Rimuovere %1$s?
@@ -2749,13 +2698,18 @@
Torna indietro
+
+ Apri riquadro di navigazione a scomparsa per il debug
+
Strumenti per le schedeConteggio schede
- Attive
+ Attive
+
+ AttiveInattive
@@ -2766,6 +2720,16 @@
Strumento per la creazione di schedeNumero di schede da creare
+
+ Il campo di testo è vuoto
+
+ Inserire solo numeri interi positivi
+
+ Inserire un numero maggiore di zero
+
+ Superato il numero massimo di schede (%1$s) che è possibile generare in una singola operazioneAggiungi a schede attive
@@ -2782,11 +2746,11 @@
Informativa sulla privacy
- Invia
+ Invia
- Chiudi
+ Chiudi
- Grazie per aver condiviso la tua opinione.
+ Grazie per aver condiviso la tua opinione.Molto soddisfatto/a
@@ -2798,6 +2762,14 @@
Molto insoddisfatto/a
+
+
+ Apri sondaggio
+
+ Chiudi sondaggio
+
+ Chiudi
+
Credenziali
diff --git a/mobile/android/fenix/app/src/main/res/values-iw/strings.xml b/mobile/android/fenix/app/src/main/res/values-iw/strings.xml
index 6afb865f1c..934a428d3c 100644
--- a/mobile/android/fenix/app/src/main/res/values-iw/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-iw/strings.xml
@@ -199,6 +199,10 @@
תוספותהרחבות
+
+ ניהול הרחבות
+
+ גילוי הרחבות נוספותמידע על החשבון
@@ -217,6 +221,8 @@
פתיחה בלשונית רגילההוספה למסך הבית
+
+ הוספה למסך הבית…התקנה
@@ -228,9 +234,13 @@
תרגום הדף
+ שמירה לאוסף…
+
שמירה לאוסףשיתוף
+
+ שיתוף…פתיחה ב־%1$s
@@ -283,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
שמירה
+
+ יצירת סימנייה לדף זה
+
+ עריכת סימנייה
+
+ שמירה כ־PDF…
+
+ הפעלת תצוגת קריאה
+
+ כיבוי תצוגת קריאה
+
+ תרגום הדף…
+
+ תורגם ל%1$s
+
+ הדפסה…
+
אין כאן הרחבות
@@ -379,8 +407,6 @@
הצהרת הפרטיות של Firefox
-
- מידע נוסף בהצהרת הפרטיות שלנואנחנו אוהבים לשמור עליךשפה
- תרגום
+ תרגום
+
+ תרגומיםבחירות נתונים
@@ -660,10 +688,6 @@
נדרשלא חובה
-
- קריאה ושינוי נתוני אתרים
-
- מחיקת אתרלאפשר לכל האתרים
@@ -794,8 +818,6 @@
היסטוריהסימניות
-
- כניסותססמאות
@@ -822,8 +844,6 @@
and the third is the device model. -->
%1$s על %2$s %3$s
-
- כרטיסי אשראיאמצעי תשלום
@@ -839,6 +859,14 @@
לשונית מהמכשיר %s
+
+
+ %2$d לשוניות נסגרו מ־%1$s
+
+ הצגת לשוניות שנסגרו לאחרונה
+
חריגות
@@ -1769,13 +1797,9 @@
באפשרותך להוסיף בקלות אתר זה למסך הבית של המכשיר שלך כדי לקבל גישה מיידית ולגלוש מהר יותר עם חוויה שמדמה שימוש ביישומון.
-
- כניסות וססמאותססמאות
- שמירת כניסות וססמאות
-
שמירת ססמאותלבקש לשמור
@@ -1792,46 +1816,27 @@
מילוי ושמירת שמות משתמשים וססמאות ביישומונים אחרים במכשיר שלך.
-
- הוספת כניסה
-
הוספת ססמה
-
- סנכרון כניסותסנכרון ססמאות
-
- סנכרון כניסות בין מכשיריםסנכרון ססמאות בין מכשירים
-
- כניסות שמורותססמאות שמורות
- הכניסות שיישמרו או יסתנכרנו אל %s יופיעו כאן.
-
הססמאות שיישמרו או יסונכרנו עם %s יופיעו כאן. כל הססמאות השמורות הינן מוצפנות.
-
- מידע נוסף על Sync.מידע נוסף על סנכרוןחריגות
-
- כניסות וססמאות שאינן שמורות יופיעו כאן.%s לא ישמור ססמאות לאתרים המפורטים כאן.
-
- כניסות וססמאות לא יישמרו עבור אתרים אלו.%s לא ישמור ססמאות לאתרים אלו.מחיקת כל החריגות
-
- חיפוש כניסותחיפוש ססמאות
@@ -1860,17 +1865,11 @@
הצגת ססמההסתרת ססמה
-
- יש לבטל את הנעילה כדי להציג את הכניסות השמורות שלךיש לבטל את הנעילה כדי להציג את הססמאות השמורות שלך
- שמירה מאובטחת של הכניסות והססמאות שלך
-
אבטחת הססמאות השמורות שלך
- ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על פרטי הגישה והססמאות השמורות שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך.
-
ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על הססמאות השמורות שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך.מאוחר יותר
@@ -1888,8 +1887,6 @@
שם (A-Z)שימוש אחרון
-
- תפריט מיון כניסותתפריט מיון ססמאות
@@ -1899,42 +1896,28 @@
מילוי אוטומטיכתובות
-
- כרטיסי אשראיאמצעי תשלום
- שמירה ומילוי אוטומטי של כרטיסים
-
שמירה ומילוי אמצעי תשלום
-
- הנתונים מוצפנים%s מצפין את כל אמצעי התשלום השמוריםסנכרון כרטיסים בין מכשיריםסנכרון כרטיסים
-
- הוספת כרטיס אשראיהוספת כרטיס
-
- ניהול כרטיסים שמוריםניהול כרטיסיםהוספת כתובתניהול כתובות
-
- שמירה ומילוי אוטומטי של כתובותשמירה ומילוי כתובות
-
- לכלול מידע כמו מספרים, כתובות דוא״ל וכתובות למשלוחכולל מספרי טלפון וכתובות דוא״ל
@@ -1958,8 +1941,6 @@
מחיקת כרטיס
- האם ברצונך למחוק את כרטיס האשראי הזה?
-
למחוק את הכרטיס?מחיקה
@@ -1973,24 +1954,15 @@
כרטיסים שמורים
-
- נא להכניס מספר כרטיס אשראי תקין
-
נא להכניס מספר כרטיס תקני
-
- נא למלא שדה זההוספת שםיש לבטל את הנעילה כדי להציג את הכרטיסים השמורים שלך
- אבטחת כרטיסי האשראי שלך
-
אבטחת אמצעי התשלום השמורים שלך
- ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על כרטיסי האשראי השמורים שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך.
-
ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על אמצעי התשלום השמורים שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך.להגדיר כעת
@@ -1999,9 +1971,6 @@
שחרור נעילת המכשיר שלך
-
- יש לבטל את הנעילה כדי להשתמש בפרטי כרטיס האשראי השמור
-
יש לבטל את הנעילה כדי להשתמש באמצעי התשלום השמורים שלך
@@ -2010,12 +1979,6 @@
עריכת כתובתניהול כתובות
-
- שם פרטי
-
- שם אמצעי
-
- שם משפחהשם
@@ -2039,9 +2002,6 @@
מחיקת כתובת
-
- האם ברצונך למחוק את כתובת זו?
-
למחוק את הכתובת הזאת?
@@ -2141,49 +2101,29 @@
מחיקהעריכה
-
- האם ברצונך למחוק את כניסה זו?האם ברצונך למחוק ססמה זו?מחיקהביטול
-
- אפשרויות כניסהאפשרויות ססמה
-
- שדה הטקסט הניתן לעריכה עבור כתובת האתר של הכניסה.שדה הטקסט הניתן לעריכה עבור כתובת האתר.
-
- שדה הטקסט הניתן לעריכה עבור שם המשתמש של הכניסה.שדה הטקסט הניתן לעריכה עבור שם המשתמש.
- שדה הטקסט הניתן לעריכה עבור הססמה של הכניסה.
-
שדה הטקסט הניתן לעריכה עבור הססמה.
-
- שמירת השינויים של הכניסה.שמירת שינויים.
-
- עריכהעריכת הססמה
-
- הוספת כניסה חדשההוספת ססמה
-
- נדרשת ססמהנא להכניס ססמה
- דרוש שם משתמש
-
נא להכניס שם משתמשדרוש שם מארח
@@ -2592,6 +2532,9 @@
סגירת גיליון התרגומים
+
+ זמנית, חלק מההגדרות אינן זמינות.
+
תרגומים
@@ -2614,6 +2557,9 @@
יש לבחור שפה כדי לנהל את ההעדפות של ״תמיד לתרגם״ ו״לעולם לא לתרגם״.
+
+ לא ניתן היה לטעון שפות. נא לנסות שוב מאוחר יותר.
+
להציע לתרגם (ברירת מחדלץ)
@@ -2636,6 +2582,8 @@
להסיר את %1$s
+
+ לא ניתן היה לטעון אתרים. נא לנסות שוב מאוחר יותר.למחוק את %1$s?
@@ -2714,13 +2662,18 @@
ניווט אחורה
+
+ פתיחת מגירת ניפוי השגיאות
+
כלי לשוניותספירת לשוניות
- פעיל
+ פעיל
+
+ פעיליםלא פעיל
@@ -2731,6 +2684,16 @@
כלי ליצירת לשוניותכמות הלשוניות ליצירה
+
+ שדה הטקסט ריק
+
+ נא להכניס מספרים שלמים חיוביים בלבד
+
+ נא להכניס מספר הגדול מאפס
+
+ חריגה ממספר הלשוניות המירבי (%1$s) שניתן ליצור בפעולה אחתהוספה ללשוניות פעילות
@@ -2747,11 +2710,11 @@
הצהרת פרטיות
- שליחה
+ שליחה
- סגירה
+ סגירה
- תודה על המשוב שלך!
+ תודה על המשוב שלך!מאוד מרוצה
@@ -2763,6 +2726,14 @@
מאוד לא מרוצה
+
+
+ פתיחת סקר
+
+ סגירת סקר
+
+ סגירה
+
כניסות
diff --git a/mobile/android/fenix/app/src/main/res/values-ja/strings.xml b/mobile/android/fenix/app/src/main/res/values-ja/strings.xml
index 5040b99f60..cad2df70fa 100644
--- a/mobile/android/fenix/app/src/main/res/values-ja/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-ja/strings.xml
@@ -51,12 +51,20 @@
- 最近保存
+ 最近保存
- 保存したブックマークをすべて表示します
+ 保存したブックマークをすべて表示します
- 削除
+ 削除
+
+
+
+ ブックマーク
+
+ すべてのブックマークを表示
+
+ 削除%1$s は Mozilla の製品です。
@@ -147,8 +155,10 @@
新しいプライベートタブ
-
- パスワードのショートカット
+
+ パスワード
+
+ パスワードのショートカット
@@ -193,6 +203,10 @@
アドオン拡張機能
+
+ 拡張機能を管理
+
+ 拡張機能を探すアカウント情報
@@ -211,18 +225,26 @@
通常タブで開くホーム画面に追加
+
+ ホーム画面に追加...インストール再同期ページ内検索
+
+ ページ内を検索...ページを翻訳
+ コレクションに保存...
+
コレクションに保存共有
+
+ 共有...%1$s で開く
@@ -252,9 +274,47 @@
ホームページをカスタマイズ
- ログイン
-
- パスワード、タブなどを同期します
+ ログイン
+
+ パスワード、タブなどを同期します
+
+
+ ログインして Sync に戻る
+
+ 同期を一時停止中
+
+ 新しいプライベートタブ
+
+ パスワード
+
+
+ %1$s の新着情報
+
+ PC 版サイトに切り替える
+
+ ツール
+
+ 保存
+
+
+ このページをブックマーク
+
+ ブックマークを編集
+
+ PDF として保存...
+
+ リーダービューで開く
+
+ リーダービューを閉じる
+
+ ページを翻訳...
+
+ %1$s に翻訳しました
+
+ 印刷...
@@ -353,8 +413,6 @@
Firefox のプライバシー通知
-
- 詳細はプライバシー通知をご覧ください私たちはあなたの安全を守りたいと願っています言語
+
+ 翻訳
+
+ 翻訳データの選択
@@ -633,6 +695,17 @@
許可されていません
+
+
+ 必須
+
+ 任意
+
+ すべてのサイトで許可する
+
+
+ この拡張機能を信頼する場合は、すべてのウェブサイトに対して権限を与えられます。
+
カスタムアドオンコレクション
@@ -656,7 +729,9 @@
以前表示したタブ
- 最近追加したブックマーク
+ 最近追加したブックマーク
+
+ ブックマーク最近訪れたサイト
@@ -751,8 +826,6 @@
表示履歴ブックマーク
-
- ログイン情報パスワード
@@ -779,8 +852,6 @@
and the third is the device model. -->
%2$s %3$s 上の %1$s
-
- クレジットカード情報支払い方法
@@ -797,6 +868,14 @@
%s からのタブ
+
+
+ %1$s のタブを %2$d 個閉じました
+
+ 最近閉じたタブを表示
+
例外
@@ -1735,13 +1814,9 @@
このウェブサイトを端末のホーム画面に簡単な操作で追加できます。アプリのような感覚で素早くアクセスして閲覧しましょう。
-
- ログイン情報とパスワードパスワード
- ログイン情報を保存する
-
パスワードを保存保存するか確認する
@@ -1757,46 +1832,27 @@
端末上の他のアプリにユーザー名とパスワードを入力します。
-
- ログイン情報を追加
-
パスワードを追加
-
- ログイン情報を同期パスワードを同期
-
- 端末間でログイン情報を同期します端末間でパスワードを同期
-
- 保存されたログイン情報保存されたパスワード
- 端末に保存または %s と同期したログイン情報がここに表示されます。
-
%s に保存または同期したパスワードがこのリストに表示されます。保存されたすべてのパスワードは暗号化されます。
-
- Sync についての詳細情報。Sync についての詳細情報例外
-
- ログイン情報が保存されないサイトがここに表示されます。%s は、このリストに表示されているサイトのパスワードを保存しません。
-
- これらのサイトではログイン情報が保存されません。%s はこれらのサイトのパスワードを保存しません。すべての例外を削除
-
- ログイン情報を検索パスワードを検索
@@ -1825,17 +1881,11 @@
パスワードを表示パスワードを隠す
-
- ロック解除して保存されたログイン情報を表示します保存されたパスワードを表示するにはロック解除してください
- ログイン情報とパスワードの保護
-
保存されたパスワードを保護してください
- 端末のロックパターンや PIN、パスワードを設定して、保存されたログイン情報とパスワードを他人の不正なアクセスから保護しましょう。
-
端末のロックパターンや PIN、パスワードを設定して、保存されたパスワードを他人の不正なアクセスから保護しましょう。後で
@@ -1853,8 +1903,6 @@
名前 (昇順)最終使用日時
-
- ログイン情報メニューの並べ替えパスワードを並べ替えます
@@ -1864,29 +1912,19 @@
自動入力所在地フォーム
-
- クレジットカード支払い方法
- カード情報を保存して自動入力する
-
支払い方法を保存して入力する
-
- データは暗号化されています%s は保存したすべての支払い方法を暗号化します端末間でカード情報を同期するクレジットカード情報を同期
-
- クレジットカードを追加カード情報を追加
-
- 保存したカードを管理カード情報を管理
@@ -1894,12 +1932,8 @@
アドレスの管理
-
- アドレスを保存して自動入力する住所を保存して入力する
-
- カード番号、メールアドレス、配送先などの情報を含める電話番号とメールアドレスを含みます
@@ -1924,8 +1958,6 @@
カードを削除
- 本当にこのクレジットカード情報を削除してもよろしいですか?
-
カード情報を削除しますか?削除
@@ -1939,25 +1971,16 @@
保存したカード
-
- 有効なクレジットカード番号を入力してください
-
正しいカード番号を入力してください
-
- このフィールドは入力必須です名前を追加してください保存されたカード情報を表示するにはロック解除してください
-
- クレジットカード情報の保護保存された支払い方法を保護してください
- 端末のロックパターンや PIN、パスワードを設定して、保存されたクレジットカード情報とパスワードを他人の不正なアクセスから保護しましょう。
-
端末のロックパターンや PIN、パスワードを設定して、保存された支払い方法を他人の不正なアクセスから保護しましょう。今すぐ設定
@@ -1966,9 +1989,6 @@
端末のロック解除
-
- ロックを解除して保存したクレジットカード情報を使用します
-
保存された支払い方法を使用するにはロック解除してください
@@ -1977,12 +1997,6 @@
住所の編集アドレスの管理
-
- 名
-
- ミドルネーム
-
- 姓氏名
@@ -2008,8 +2022,6 @@
アドレスを削除
-
- 本当にこの住所を削除してもよろしいですか?このアドレスを削除しますか?
@@ -2108,8 +2120,6 @@
削除編集
-
- このログイン情報を削除してもよろしいですか?本当にこのパスワードを削除してもよろしいですか?
@@ -2117,41 +2127,23 @@
キャンセル
-
- ログインオプションパスワードのオプション
-
- ログイン情報のウェブアドレスの編集可能なテキストフィールド。ウェブサイトのアドレスの編集可能なテキストフィールド。
-
- ログイン情報のユーザー名の編集可能なテキストフィールド。ユーザー名の編集可能なテキストフィールド。
- ログイン情報のパスワードの編集可能なテキストフィールド。
-
パスワードの編集可能なテキストフィールド。
-
- 変更を保存してログインします。変更を保存します。
-
- 編集パスワードを編集
-
- 新しいログイン情報の追加パスワードを追加
-
- パスワードが必要ですパスワードを入力してください
- ユーザー名は必須です
-
ユーザー名を入力してくださいホスト名は必須です
@@ -2497,10 +2489,14 @@
翻訳元翻訳先
+
+ 別の翻訳元言語を試す後で元の言語で表示
+
+ 翻訳されていない元のページが読み込まれました完了
@@ -2520,7 +2516,7 @@
申し訳ありませんが、%1$s はまだサポートされていません。
- 詳細情報
+ 詳細情報翻訳中…
@@ -2535,7 +2531,9 @@
- 翻訳オプション
+ 翻訳オプション
+
+ 翻訳オプション常に翻訳機能を提供する
@@ -2553,6 +2551,12 @@
%1$s の翻訳機能について
+
+ 翻訳シートを閉じる
+
+
+ 一部の設定が一時的に利用できません。
+
翻訳
@@ -2576,6 +2580,9 @@
設定で「常に翻訳する」言語と「翻訳しない」言語を選択します。
+
+ 言語を読み込めませんでした。後でもう一度ご確認ください。
+
翻訳を通知する (既定)
@@ -2598,6 +2605,8 @@
%1$s を削除します
+
+ サイトを読み込めませんでした。後でもう一度ご確認ください。%1$s を削除しますか?
@@ -2675,12 +2684,19 @@
デバッグツール前のページへ戻ります
+
+
+ デバッグパネルを開く
+
+
タブツールタブ数
- 使用中
+ 使用中
+
+ 使用中休止中
@@ -2691,10 +2707,63 @@
タブ作成ツール作成するタブの数
+
+ テキストフィールドが空です
+
+ 正の整数を入力してください
+
+ 0 より大きい数字を入力してください
+
+ 1 回の操作で生成できるタブの上限 (%1$s 個) に達しました使用中のタブに追加休止中のタブに追加プライベートタブに追加
+
+
+
+
+ 続ける
+
+ このアンケートにご回答ください
+
+ プライバシー通知
+
+ 送信
+
+ 閉じる
+
+ フィードバックのご提供ありがとうございます。
+
+ とても満足
+
+ 満足
+
+ どちらでもない
+
+ 不満
+
+ 非常に不満
+
+
+
+ アンケートを開く
+
+ アンケートを閉じる
+
+ 閉じる
+
+
+
+ ログイン情報
+
+ 現在のドメイン: %s
+
+ このドメインの疑似ログイン情報を追加
+
+ ユーザー名 %s のログイン情報を削除します
diff --git a/mobile/android/fenix/app/src/main/res/values-kab/strings.xml b/mobile/android/fenix/app/src/main/res/values-kab/strings.xml
index 65fa7f8a0c..0c17e45335 100644
--- a/mobile/android/fenix/app/src/main/res/values-kab/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-kab/strings.xml
@@ -51,12 +51,20 @@
- Yettwasekles melmi kan
+ Yettwasekles melmi kan
- Sken akk ticraḍ n yisebtar yettwaskelsen
+ Sken akk ticraḍ n yisebtar yettwaskelsen
- Kkes
+ Kkes
+
+
+
+ Ticraḍ n yisebtar
+
+ Sken akk ticraḍ n yisebtar
+
+ Kkes%1$s d afares n Mozilla.
@@ -196,6 +204,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
IzegrarIsiɣzaf
+
+ Sefrek isiɣzafTalut n umiḍan
@@ -220,12 +230,18 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Ales amtawiNadi deg usebter
+
+ Nadi deg usebter…Suqel asebter
+ Sekles deg tegrumma…
+
Sekles ɣer tegrummaBḍu
+
+ Bḍu…Ldi di %1$s
@@ -257,6 +273,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
KcemMtawi awalen n uεeddi, accaren akked wayen niḍen
+
+ Ales qqen i wakken ad tesnekreḍ amtawi
+
+ Amtawa yeḥbesIccer uslig amaynut
@@ -265,6 +285,28 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
The first parameter is the name of the app defined in app_name (for example: Fenix)-->
Amaynut deg %1$s
+
+ Ddu ɣer usmel n tnarit
+
+ Ifecka
+
+ Sekles
+
+
+ Creḍ asebter-a
+
+ Ẓreg tacreḍt n usebter
+
+ Kles d PDF…
+
+ Suqel asebter…
+
+ Suqqel ɣer %1$s
+
+ Siggez…
+
Ulac isiɣzaf dagi
@@ -280,6 +322,11 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Suqel asebter
+
+ Asebter yettwasuqqel seg %1$s ɣer %2$s.
+
Fren tutlayt
@@ -358,8 +405,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Tasertit tabaḍnit n Firefox
-
- Issin ugar deg tsertit-nneɣ n tbaḍnitNḥemmel ad teqqimeḍ d aɣellsan
@@ -550,6 +595,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Ales tuqqna akken ad ikemmel umtawiTutlayt
+
+ Tasuqilt
+
+ TisuqilinAfran n yisefka
@@ -604,6 +653,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Izegrar
+
+ IsiɣzafSebded azegrir seg ufaylu
@@ -621,10 +672,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
YettawsraAfrayan
-
- Γeṛ syen tesnefleḍ isefka n usmel web
-
- Kkes asmel web
+
+
+ Sireg meṛṛa ismal
@@ -645,7 +695,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Uɣal ɣer deffir
- Ticraḍ n yisebtar n melmi kan
+ Ticraḍ n yisebtar n melmi kan
+
+ Ticraḍ n yisebtarYemmẓer melmi kan
@@ -697,18 +749,27 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Izegrar imaynuten llan tura
+
+ Llan akka tura isiɣzaf imaynutenSnirem ugar n 100 yisiɣzaf imaynuten ara ak·akem-yeǧǧen ad tsagneḍ Firefox.Snirem izegrar
+
+ Snirem isiɣzaf
+
Azegrir yensa i kra n wakud
+
+ Isiɣzaf nsan i kra n wakudYiwen neɣ ugar n yizegrar ḥebsen, rran anagraw-ik d arurkid. %1$s ur yessaweḍ ara ad yales asenker n uzegrir(yizegrar).\n\nIzegrar ugin ad alsen tanekra ɣef teɣzi n tiɣimit-a.\n\Kkes neɣ sens izegrar-a, ahat ad yefru wugur-a.Ɛreḍ asenker n uzegrir
+
+ Ԑreḍ allus n usenker n yisiɣzafKemml s uzegrir yensa
@@ -725,8 +786,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
AzrayTicraḍ n yisebtar
-
- InekcamAwalen uffiren
@@ -754,8 +813,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
and the third is the device model. -->
%1$s deg %2$s %3$s
-
- Tikarḍiwin n usmadTarrayin n uxelleṣ
@@ -1708,13 +1765,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Tzemreḍ s sshal ad ternuḍ asmel-a web ɣer ugdil agejdan n yibenk-inek·inem i wakken ad tesɛuḍ anekcum askudan d tunigin taruradt s termt i icuban asnas.
-
- Inekcam d wawalen uffirenAwalen uffiren
- Sekles inekcam d wawalen uffiren
-
Sekles awalen uffirenSuter asekles
@@ -1730,38 +1783,19 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Ččar ismawen n useqdac d wawalen uffiren deg yisnasen-nniḍen ɣef yibenk-ik·im.
-
- Rnu anekcum
-
Rnu awal uffir
-
- Mtawi inekcamMtawi awalen uffiren
-
- Mtawi inekcam gqr yibenkan
-
- Inekcam yettwakelsenAwalen uffiren yettwakelsen
-
- Anekcum i tḥerzeḍ ɣer %s ad d-ittwasken da.
-
- Issin ugar ɣef umtawi.Issin ugar ɣef umtawiTisuraf
-
- Inekcam akked wawalen uffiren ur yettwaskelsen ara ad ttwaseknen dagi.
-
- Inekcam akked wawalen uffiren ur ttwaseklasen ara i yismal-a.Kkes akk tisuraf
-
- Nadi inekcamNadi awalen uffiren
@@ -1790,14 +1824,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Sken awal uffirFfer awal uffir
-
- Serreḥ akken ad tsekneḍ inekcam-ik yettwaskelsen
-
- Mmesten inekcam d wawalen uffirenSeɣles awalen-ik·im uffiren i yettwaskelsen
-
- Sbadu azenziɣ n usekkeṛ, tangal PIN, neɣ awal uffir akken ad temmesteneḍ inekcam-ik akked wawlen-ik uffiren yettwaskelsen ticki yella win ikecmen ɣer yibenk-ik.Ticki
@@ -1815,44 +1843,34 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Aseqdec aneggaru
-
- Umuɣ n usemyizwer n yinekcam
+
+ Umuɣ n usmizwer n wawalen n uεeddiTaččart tawurmantTansiwin
-
- Tikarḍiwin n usmadTarrayin n uxelleṣ
- Asekles d taččart tawurmant n tkarḍiwin
-
- Isefka ttwawgelhen
+ Sekles syen ččar tarrayin n uxelleṣ
+
+ %s yettewgellih akk tarrayin n uxelleṣ i teskelseḍMtawi tikarḍiwin gar yibenkanMtawi tikarḍiwin
-
- Rnu takarḍa n usmadRnu takarḍa
-
- Sefrek tikerḍiwin yettwaskelsenSefrek tikarḍiwinRnu tansaSefrek tansiwin
-
- Asekles d taččart tawurmant n tansiwinSekles; teččareḍ tansiwin
-
- Seddu talɣut am wuṭṭunen, imayl akked tansiwin n usiweḍSeddu ula uṭṭunen n tiliɣri d tansiwin n yimayl
@@ -1876,8 +1894,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Kkes takarḍa
- Tebɣiḍ s tidet ad tekkseḍ takarḍa-a n usmad?
-
Kkes takarḍa?Kkes
@@ -1890,42 +1906,31 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Tikerḍiwin yettwasekles
-
- Ma ulac aɣilif sekcem uṭṭun ameɣtu n tkarḍa n usmad
-
Sekcem uṭṭun n tkarḍa ameɣtu
-
- Ttxil-k·m ččar urti-aRnu isemKkes asekkeṛ i wakken ad twaliḍ tikerḍiwin-ik·im yettwaskelsen
- Seɣles tikerḍiwin-ik·im n usmad
+ Seɣles tarrayin-ik n uxelleṣ i yettwaskelsen
- Sbadu taneɣruft n usekkeṛ n yibenk, tangalt PIN neq awal uffir i ummesten n tkerḍiwin-ik·im n usmad yettwaskelsen ticki yella win ikecmen ɣer yibenk-inek·inem.
+ Sbadu taneɣruft n usekkeṛ n yibenk, tangalt PIN neq awal uffir i ummesten n tarrayin-ik·im n usmad yettwaskelsen ticki yella win ikecmen ɣer yibenk-inek·inem.Sbadu turaTickiSerreḥ i ibenk-inek·inem
-
- Kkes asekkeṛ i wakken ad tesqedceḍ talɣut n tkarḍa n usmad
+
+ Kkes asekkeṛ tarrayin-ik n uxelleṣ i yettwaskelsenRnu tansaẒreg tansaSefrek tansiwin
-
- Aɣara
-
- Isem alemmas
-
- IsemIsem
@@ -1951,8 +1956,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Kkes tansa
-
- D tidet tebɣiḍ ad tekkseḍ tansa-a?Kkes tansa-a?
@@ -2053,41 +2056,29 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
KkesẒreg
-
- Tebɣiḍ ad tekseḍ anekcum-agi?
+
+ D tidet tebɣiḍ ad tekkseḍ awal-a n uεeddi?KkesSefsex
-
- Iɣewwaren n unekcumTixtiṛiyin n wawal uffir
-
- Urti n uḍris yettusenfal i tansa n unekcum n web.
-
- Urti n uḍris yettusenfal i yisem n useqdac n unekcum.
+
+ Urti n uḍris yettusenfal i tansa n usmel web.
+
+ Urti n uḍris yettusenfal i yisem n useqdac.
- Urti n uḍris yettusenfal i wawal uffir n unekcum.
-
- Sekles isenfaln unekcum.
+ Urti n uḍris yettusenfal i wawal n uεeddi.Sekles isenfal.
-
- ẒregẒreg awal uffir
-
- Rnu anekcum amaynutRnu awal uffir
-
- Awal uffir yettusraSekcem awal uffir
- Isem n useqdac yettwasra
-
Sekcem isem n useqdacAsenneftaɣ yettwasra
@@ -2510,7 +2501,7 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Amḍan n waccaren
- Urmid
+ UrmidInsa
@@ -2518,12 +2509,50 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Asemday
+
+ Rnu ɣer waccaren urmiden
+
+ Rnu ɣer waccaren irurmiden
+
+ Rnu ɣer waccaren usligen
+
+
+ Kemmel
+
+ Smed aḥedqis-a
+
+ Tasertit n tbaḍnit
+
+ Azen
+
+ Mdel
+
+ Tanemmirt ɣef tekti yinek!
+
+ Yumer aṭas
+
+ Y·TumerWar tamawt
+
+ Ur yumir ara
+
+ Texseṛ-as akk nniya
+
+
+
+ Ldi aḥedqis
+
+ Mdel aḥedqis
+
+ Mdel
+
Inekcam
+
+ Taɣult-a: %s
diff --git a/mobile/android/fenix/app/src/main/res/values-kk/strings.xml b/mobile/android/fenix/app/src/main/res/values-kk/strings.xml
index eec9afe73c..cb9da8fe5c 100644
--- a/mobile/android/fenix/app/src/main/res/values-kk/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-kk/strings.xml
@@ -198,6 +198,10 @@
ҚосымшаларКеңейтулер
+
+ Кеңейтулерді басқару
+
+ Көбірек кеңейтулерді табуТіркелгі ақпараты
@@ -216,6 +220,8 @@
Қалыпты бетте ашуҮй экранына қосу
+
+ Үй экранына қосу…Орнату
@@ -227,9 +233,13 @@
Парақты аудару
+ Жинаққа сақтау…
+
Жинаққа сақтауБөлісу
+
+ Бөлісу…%1$s көмегімен ашу
@@ -282,6 +292,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Сақтау
+
+ Бұл бетті бетбелгілерге қосу
+
+ Бетбелгіні түзету
+
+ PDF ретінде сақтау…
+
+ Оқу көрінісін іске қосу
+
+ Оқу көрінісін сөндіру
+
+ Парақты аудару…
+
+ %1$s тіліне аударылған
+
+ Баспаға шығару…
+
Мұнда кеңейтулер жоқ
@@ -379,8 +407,6 @@
Firefox жекелік ескертуі
-
- Біздің жекелік ескертуімізден көбірек біліңізБіз сіздің қауіпсіздігіңізді қамтамасыз етуді жақсы көремізТіл
- Аударма
+ Аударма
+
+ АудармаларДеректер таңдауы
@@ -663,10 +691,6 @@
МіндеттіМіндетті емес
-
- Веб-сайт деректерін оқу және өзгерту
-
- Веб-сайтты өшіруБарлық сайттар үшін рұқсат ету
@@ -792,8 +816,6 @@
Шолу тарихыБетбелгілер
-
- ЛогиндерПарольдер
@@ -819,8 +841,6 @@
and the third is the device model. -->
%1$s, %2$s %3$s
-
- Несиелік карталарТөлем әдістері
@@ -836,6 +856,14 @@
%s құрылғысынан бет
+
+
+ %1$s бет жабылды: %2$d
+
+ Жақында жабылған беттерді қарау
+
Ережеден бөлек
@@ -1761,13 +1789,9 @@
Бұл веб-сайтты жылдам қатынау және қолданба тектес режимде жылдам шолу мақсатымен құрылғыңыздың үй бетіңізге қосуға болады.
-
- Логиндер және парольдерПарольдер
- Логиндер және парольдерді сақтау
-
Парольдерді сақтауСақтау алдында сұрау
@@ -1784,46 +1808,27 @@
Құрылғыңыздағы басқа қолданбаларда пайдаланушы аттары мен парольдерін толтыру.
-
- Логинді қосу
-
Парольді қосу
-
- Логиндерді синхрондауПарольдерді синхрондау
-
- Логиндерді құрылғылар арасында синхрондауПарольдерді құрылғылар арасында синхрондау
-
- Сақталған логиндерСақталған парольдер
- Сіз %s ішінде сақтаған немесе синхрондаған логиндер осында көрсетіледі.
-
Сіз %s ішіне сақтаған немесе синхрондаған парольдер осында тізіліп көрсетіледі. Сіз сақтаған барлық парольдер шифрленген.
-
- Синхрондау туралы көбірек біліңіз.Синхрондау туралы көбірек біліңізЕрежеден бөлек
-
- Сақталмаған логиндер мен парольдер осында көрсетіледі.%s осы жерде тізімделген сайттар үшін парольдерді сақтамайтын болады.
-
- Бұл сайттар үшін логиндер мен парольдер сақталмайды.%s бұл сайттар үшін парольдерді сақтамайтын болады.Барлық ережеден тыс жағдайларды өшіру
-
- Логиндерден іздеуПарольдерді іздеу
@@ -1852,17 +1857,11 @@
Парольді көрсетуПарольді жасыру
-
- Сақталған логиндеріңізді көру үшін бұғаттауын ашыңызСақталған парольдеріңізді көру үшін бұғаттауын ашыңыз
- Логиндер және парольдерді қорғаңыз
-
Сақталған парольдерді қорғаңыз
- Бөтен адам сіздің құрылғыңызда болса, одан сақталған логиндер мен парольдерді қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз.
-
Бөтен адам сіздің құрылғыңызда болса, одан сақталған парольдеріңізді қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз.Кейінірек
@@ -1879,8 +1878,6 @@
Аты (А-Я)Соңғы қолданылған
-
- Логиндерді сұрыптау мәзіріПарольдерді сұрыптау мәзірі
@@ -1890,41 +1887,27 @@
АвтотолтыруАдрестер
-
- Несиелік карталарТөлем әдістері
- Карталарды сақтау және автотолтыру
-
Төлем әдістерін сақтау және толтыру
-
- Деректер шифрленген%s сіз сақтаған барлық төлем әдістерін шифрлейдіКарталарды құрылғылар арасында синхрондауКарталарды синхрондау
-
- Несиелік картаны қосуКартаны қосу
-
- Сақталған карталарды басқаруКарталарды басқаруАдресті қосуАдрестерді басқару
-
- Адрестерді сақтау және автотолтыруАдрестерді сақтау және толтыру
-
- Нөмірлер, эл. пошта және жеткізу адрестері сияқты ақпаратты қосуТелефон нөмірлері мен электрондық пошта адрестерін қамтиды
@@ -1948,8 +1931,6 @@
Картаны өшіру
- Бұл несие картасын өшіруді шынымен қалайсыз ба?
-
Картаны өшіру керек пе?Өшіру
@@ -1963,24 +1944,15 @@
Сақталған карталар
-
- Несиелік картаның жарамды нөмірін енгізіңіз
-
Жарамды карта нөмірін енгізіңіз
-
- Бұл өрісті толтырыңызАтын қосыңызСақталған карталарыңызды көру үшін бұғаттауын ашыңыз
- Несиелік карталарыңызды қорғаңыз
-
Сақталған төлем әдістерін қорғаңыз
- Бөтен адам сіздің құрылғыңызда болса, одан сақталған несиелік карталарды қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз.
-
Бөтен адам сіздің құрылғыңызда болса, одан сақталған төлем әдістерін қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз.Қазір баптау
@@ -1989,9 +1961,6 @@
Құрылғының бұғаттауын ашыңыз
-
- Сақталған несиелік карта ақпаратын қолдану үшін бұғаттауын ашыңыз
-
Сақталған төлем әдістерін қолдану үшін құлыптан босатыңыз
@@ -2000,12 +1969,6 @@
Адресті түзетуАдрестерді басқару
-
- Аты
-
- Әкесінің аты
-
- ТегiАты
@@ -2032,8 +1995,6 @@
Адресті өшіру
-
- Бұл адресті өшіруді шынымен қалайсыз ба?Бұл адресті өшіру керек пе?
@@ -2131,50 +2092,30 @@
ӨшіруТүзету
-
- Бұл логинді өшіруді қалайсыз ба?Бұл парольді өшіруді шынымен қалайсыз ба?ӨшіруБас тарту
-
- Логин баптауларыПароль опциялары
-
- Логиннің веб-адресі үшін түзетуге болатын мәтіндік өрісі.Веб-сайт адресі үшін түзетуге болатын мәтіндік өрісі.
-
- Логиннің пайдаланушы аты үшін түзетуге болатын мәтіндік өрісі.Пайдаланушы аты үшін түзетуге болатын мәтіндік өрісі.
-
- Логиннің паролі үшін түзетуге болатын мәтіндік өрісі.Пароль үшін түзетуге болатын мәтіндік өрісі.
-
- Логин өзгерістерін сақтау.Өзгерістерді сақтау.
-
- ТүзетуПарольді түзету
-
- Жаңа логинді қосуПарольді қосу
-
- Пароль керекПарольді енгізіңіз
- Пайдаланушы аты керек
-
Пайдаланушы атын енгізіңізХост атауы керек
@@ -2524,6 +2465,8 @@
Қазір емесТүпнұсқаны көрсету
+
+ Аударылмаған түпнұсқа бет жүктелдіДайын
@@ -2582,6 +2525,9 @@
Аудармалар парағын жабу
+
+ Кейбір баптаулар уақытша қолжетімсіз.
+
Аудармалар
@@ -2604,6 +2550,9 @@
"әрқашан аудару" және "ешқашан аудармау" баптауларды басқару үшін тілді таңдаңыз.
+
+ Тілдерді жүктеу мүмкін емес. Кейінірек қайта тексеріңіз.
+
Аударуды ұсыну (үнсіз келісім бойынша)
@@ -2627,6 +2576,8 @@
%1$s өшіру
+
+ Сайттарды жүктеу мүмкін емес. Кейінірек қайта тексеріңіз.%1$s өшіру керек пе?
@@ -2705,13 +2656,18 @@
Артқа өту
+
+ Жөндеу сөресін ашу
+
Беттер саймандарыБеттер саны
- Белсенді
+ Белсенді
+
+ БелсендіБелсенді емес
@@ -2722,6 +2678,16 @@
Беттерді жасау құралыЖасау үшін беттер саны
+
+ Мәтін өрісі бос
+
+ Тек оң сандарды енгізіңіз
+
+ Нөлден үлкен санды енгізіңіз
+
+ Беттер саны бір әрекетте жасауға болатын максималды санынан (%1$s) астыБелсенді беттерге қосу
@@ -2738,11 +2704,11 @@
Жекелік ескертуі
- Жіберу
+ Жіберу
- Жабу
+ Жабу
- Пікіріңізге рахмет!
+ Пікіріңізге рахмет!Өте жақсы
@@ -2754,6 +2720,14 @@
Өте нашар
+
+
+ Сауалнаманы ашу
+
+ Сауалнаманы жабу
+
+ Жабу
+
Логиндер
diff --git a/mobile/android/fenix/app/src/main/res/values-ko/strings.xml b/mobile/android/fenix/app/src/main/res/values-ko/strings.xml
index 3d14dbadd0..5da118bfc3 100644
--- a/mobile/android/fenix/app/src/main/res/values-ko/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-ko/strings.xml
@@ -205,6 +205,10 @@
부가 기능확장 기능
+
+ 확장 기능 관리
+
+ 더 많은 확장 기능 살펴보기계정 정보
@@ -223,6 +227,8 @@
일반 탭에서 열기홈 화면에 추가
+
+ 홈 화면에 추가…설치
@@ -234,9 +240,13 @@
페이지 번역
+ 모음집에 저장…
+
모음집에 저장공유
+
+ 공유…%1$s에서 열기
@@ -291,6 +301,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
저장
+
+ 이 페이지 북마크
+
+ 북마크 편집
+
+ PDF로 저장…
+
+ 리더뷰 켜기
+
+ 리더뷰 끄기
+
+ 페이지 번역…
+
+ %1$s 언어로 번역됨
+
+ 인쇄…
+
확장 기능 없음
@@ -388,8 +416,6 @@
Firefox 개인정보처리방침
-
- 개인정보 보호정책에서 자세히 알아보기우리는 사용자를 안전하게 지키는 것을 좋아합니다언어
- 번역
+ 번역
+
+ 번역데이터 선택
@@ -675,10 +703,6 @@
선택 사항
-
- 웹 사이트 데이터 읽기 및 변경
-
- 웹 사이트 삭제모든 사이트에 허용
@@ -805,8 +829,6 @@
기록북마크
-
- 로그인비밀번호
@@ -833,8 +855,6 @@
and the third is the device model. -->
%2$s %3$s의 %1$s
-
- 신용 카드결제 방법
@@ -851,6 +871,14 @@
%s에서 온 탭
+
+
+ %1$s 탭 닫힘: %2$d개
+
+ 최근에 닫은 탭 보기
+
예외 목록
@@ -1812,13 +1840,9 @@
이 웹 사이트를 기기의 홈 화면에 쉽게 추가하여 앱과 같은 경험을 통해 즉시 액세스하고 더 빠르게 탐색 할 수 있습니다.
-
- 로그인과 비밀번호비밀번호
- 로그인과 비밀번호 저장
-
비밀번호 저장저장할지 묻기
@@ -1834,46 +1858,27 @@
기기의 다른 앱에서 사용자 이름과 비밀번호를 채웁니다.
-
- 로그인 추가
-
비밀번호 추가
-
- Sync 로그인비밀번호 동기화
-
- 기기 간에 로그인 동기화기기 간에 비밀번호 동기화
-
- 저장된 로그인저장된 비밀번호
- %s에 저장하거나 동기화한 로그인이 여기에 표시됩니다.
-
%s에 저장하거나 동기화한 비밀번호는 여기에 나열됩니다. 저장한 모든 비밀번호는 암호화됩니다.
-
- Sync에 대해 더 알아보기.동기화에 대해 더 알아보기예외 목록
-
- 저장되지 않은 로그인과 비밀번호가 여기에 표시됩니다.%s는 여기에 나열된 사이트의 비밀번호를 저장하지 않습니다.
-
- 이 사이트에 대한 로그인과 비밀번호는 저장되지 않습니다.%s는 이 사이트의 비밀번호를 저장하지 않습니다.모든 예외 삭제
-
- 로그인 검색비밀번호 검색
@@ -1902,17 +1907,11 @@
비밀번호 보이기비밀번호 숨기기
-
- 저장된 로그인을 보려면 잠금 해제하세요저장된 비밀번호를 보려면 잠금 해제하세요
- 로그인과 비밀번호 보안
-
저장된 비밀번호를 보호하세요
- 다른 사람이 내 기기를 가지고 있는 경우, 저장된 로그인과 비밀번호에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요.
-
다른 사람이 내 기기를 가지고 있는 경우, 저장된 비밀번호에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요.나중에
@@ -1930,8 +1929,6 @@
이름 (A-Z)마지막 사용
-
- 로그인 정렬 메뉴비밀번호 정렬 메뉴
@@ -1941,42 +1938,28 @@
자동 채우기주소
-
- 신용 카드결제 방법
- 카드 저장 및 자동 채우기
-
결제 방법 저장 및 채우기
-
- 데이터가 암호화됨%s는 저장한 모든 결제 방법을 암호화합니다기기 간에 카드 동기화카드 동기화
-
- 신용 카드 추가카드 추가
-
- 저장된 카드 관리카드 관리주소 추가주소 관리
-
- 주소 저장 및 자동 채우기주소 저장 및 채우기
-
- 숫자, 이메일 및 배송 주소와 같은 정보 포함전화번호와 이메일 주소가 포함됩니다
@@ -2001,8 +1984,6 @@
카드 삭제
- 이 신용 카드를 삭제하시겠습니까?
-
카드를 삭제하시겠습니까?삭제
@@ -2016,24 +1997,15 @@
저장된 카드
-
- 유효한 신용 카드 번호를 입력해 주세요
-
유효한 카드 번호를 입력하세요
-
- 이 항목을 입력하세요.이름 추가저장된 카드를 보려면 잠금 해제하세요
- 신용 카드 보안
-
저장된 결제 방법을 보호하세요
- 다른 사람이 내 기기를 가지고 있는 경우, 저장된 신용 카드에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요.
-
다른 사람이 내 기기를 가지고 있는 경우, 저장된 결제 방법에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요.지금 설정
@@ -2042,9 +2014,6 @@
기기 잠금 해제
-
- 저장된 신용 카드 정보를 사용하려면 잠금 해제하세요
-
저장된 결제 방법을 사용하려면 잠금 해제하세요
@@ -2053,12 +2022,6 @@
주소 편집주소 관리
-
- 이름
-
- 중간 이름
-
- 성이름
@@ -2084,8 +2047,6 @@
주소 삭제
-
- 이 주소를 삭제하시겠습니까?이 주소를 삭제하시겠습니까?
@@ -2185,49 +2146,29 @@
삭제편집
-
- 이 로그인을 삭제하시겠습니까?이 비밀번호를 삭제하시겠습니까?삭제취소
-
- 로그인 옵션비밀번호 옵션
-
- 로그인 웹 주소의 편집 가능한 텍스트 필드입니다.웹 사이트 주소에 대한 편집 가능한 텍스트 필드입니다.
-
- 로그인 사용자 이름의 편집 가능한 텍스트 필드입니다.사용자 이름에 대한 편집 가능한 텍스트 필드입니다.
- 로그인 비밀번호의 편집 가능한 텍스트 필드입니다.
-
비밀번호에 대한 편집 가능한 텍스트 필드입니다.
-
- 변경 내용을 로그인에 저장.변경 내용 저장.
-
- 편집비밀번호 수정
-
- 새 로그인 추가비밀번호 추가
-
- 비밀번호 필요비밀번호 입력
- 사용자 이름은 필수입니다
-
사용자 이름 입력호스트 이름은 필수입니다
@@ -2636,6 +2577,9 @@
번역 시트 닫기
+
+ 일부 설정을 일시적으로 사용할 수 없습니다.
+
번역
@@ -2659,6 +2603,9 @@
”항상 번역“ 및 ”번역 안 함“ 설정을 관리할 언어를 선택하세요
+
+ 언어를 로드할 수 없습니다. 나중에 다시 확인해 주세요.
+
번역 제안 (기본값)
@@ -2682,6 +2629,8 @@
%1$s 제거
+
+ 사이트를 로드할 수 없습니다. 나중에 다시 확인해 주세요.%1$s 사이트를 삭제하시겠습니까?
@@ -2761,13 +2710,18 @@
뒤로
+
+ 디버그 서랍 열기
+
탭 도구탭 수
- 활성
+ 활성
+
+ 활성비활성
@@ -2778,6 +2732,16 @@
탭 생성 도구생성할 탭 수량
+
+ 텍스트 필드가 비어 있음
+
+ 양의 정수만 입력하세요
+
+ 0보다 큰 숫자를 입력하세요
+
+ 한 번의 작업으로 생성할 수 있는 최대 탭 수(%1$s)를 초과했음활성 탭에 추가
@@ -2794,12 +2758,12 @@
개인정보처리방침
- 보내기
+ 보내기
- 닫기
+ 닫기
- 의견을 보내 주셔서 감사합니다!
+ 의견을 보내 주셔서 감사합니다!매우 만족
@@ -2811,6 +2775,14 @@
매우 불만족
+
+
+ 설문조사 열기
+
+ 설문조사 닫기
+
+ 닫기
+
로그인
diff --git a/mobile/android/fenix/app/src/main/res/values-nb-rNO/strings.xml b/mobile/android/fenix/app/src/main/res/values-nb-rNO/strings.xml
index 3479298722..d435330c22 100644
--- a/mobile/android/fenix/app/src/main/res/values-nb-rNO/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-nb-rNO/strings.xml
@@ -48,12 +48,20 @@
- Nylig lagret
+ Nylig lagret
- Vis alle lagrede bokmerker
+ Vis alle lagrede bokmerker
- Fjern
+ Fjern
+
+
+
+ Bokmerker
+
+ Vis alle bokmerker
+
+ Fjern%1$s er produsert av Mozilla.
@@ -191,6 +199,10 @@
TilleggUtvidelser
+
+ Behandle utvidelser
+
+ Oppdag flere utvidelserKontoinformasjon
@@ -210,18 +222,26 @@
Åpne i vanlig faneLegg til på startskjermen
+
+ Legg til på startskjermen…InstallerSynkroniser på nyttFinn på siden
+
+ Finn på siden…Oversett siden
+ Lagre i samling…
+
Lagre i samlingDel
+
+ Del…Åpne i %1$s
@@ -261,6 +281,34 @@
Passord
+
+ Nytt i %1$s
+
+ Bytt til datamaskinversjon
+
+ Verktøy
+
+ Lagre
+
+ Bokmerk denne siden
+
+ Rediger bokmerke
+
+ Lagre som PDF…
+
+ Slå på leservisning
+
+ Slå av leservisning
+
+ Oversett siden…
+
+ Oversatt til %1$s
+
+ Skriv ut…
+
Ingen utvidelser her
@@ -358,8 +406,6 @@
Firefox personvernerklæring
-
- Les mer i vår personvernerklæringVi beskytter deg gjerneSpråk
+
+ Oversettelse
+
+ OversettelserDatavalg
@@ -638,10 +688,6 @@
NødvendigValgfri
-
- Les og endre nettstedsdata
-
- Slett nettstedTillat for alle nettsteder
@@ -671,7 +717,9 @@
Hopp inn igjen
- Nylige bokmerker
+ Nylige bokmerker
+
+ BokmerkerNylig besøkt
@@ -765,8 +813,6 @@
HistorikkBokmerker
-
- InnloggingerPassord
@@ -793,8 +839,6 @@
and the third is the device model. -->
%1$s på %2$s %3$s
-
- BetalingskortBetalingsmåter
@@ -811,6 +855,14 @@
Fane fra %s
+
+
+ %1$s lukket %2$d faner
+
+ Vis nylig lukkede faner
+
Unntak
@@ -1742,13 +1794,9 @@
Du kan enkelt legge til dette nettstedet på enhetens startskjerm for å få øyeblikkelig tilgang og surfe raskere med en app-lignende opplevelse.
-
- Innlogginger og passordPassord
- Lagre innlogginger og passord
-
Lagre passordSpør om å lagre
@@ -1764,47 +1812,28 @@
Fyll inn brukernavn og passord i andre apper på enheten din.
-
- Legg til innlogging
-
Legg til passord
-
- Synkroniser innloggingerSynkroniser passord
-
- Synkroniser innlogginger på tvers av enheterSynkroniser passord på tvers av enheter
-
- Lagrede innloggingerLagrede passord
- De innlogginger du lagrer eller synkroniserer til %s vil vises her.
-
Passordene du lagrer eller synkroniserer med %s vil bli oppført her. Alle passord du lagrer er kryptert.
-
- Les mer om Sync.Les mer om synkroniseringUnntak
-
- Innlogginger og passord som ikke er lagret vil vises her.%s vil ikke lagre passord for nettsteder som er oppført her.
-
- Innlogginger og passord vil ikke bli lagret for disse nettstedene.%s vil ikke lagre passord for disse nettstedene.Slett alle unntak
-
- Søk innloggingerSøk etter passord
@@ -1834,17 +1863,11 @@
Vis passordSkjul passord
-
- Lås opp for å se dine lagrede innloggingerLås opp for å se dine lagrede passord
- Sikre dine innlogginger og passord
-
Sikre dine lagrede passord
- Konfigurer en PIN-kode, et passord eller et låsemønster for å forhindre at andre mennesker får tilgang de lagrede innloggingene og passordene dine, hvis de har adgang til din enhet.
-
Konfigurer en PIN-kode, et passord eller et låsemønster for å beskytte dine lagrede passord om noen andre skulle få tak i enheten din.Senere
@@ -1864,9 +1887,6 @@
Sist brukt
-
- Sorter innlogginger-meny
-
Sorter passord-menyen
@@ -1875,41 +1895,27 @@
AutofyllAdresser
-
- BetalingskortBetalingsmåter
- Lagre og fyll ut kort automatisk
-
Lagre og fyll inn betalingsmåter
-
- Data er kryptert%s krypterer alle betalingsmåter du lagrerSynkroniser kort på tvers av enheterSynkroniser kort
-
- Legg til betalingskortLegg til kort
-
- Behandle lagrede kortBehandle kortLegg til adresseBehandle adresser
-
- Lagre og autoutfyll adresserLagre og fyll ut adresser
-
- Inkluderer informasjon som telefonnummer, e-post og leveringsadresserInkluderer telefonnumre og e-postadresser
@@ -1933,8 +1939,6 @@
Slett kort
- Er du sikker på at du vil slette dette bankkortet?
-
Slett kort?Slett
@@ -1947,24 +1951,15 @@
Lagrede kort
-
- Oppgi et gyldig betalingskortnummer
-
Skriv inn et gyldig kortnummer
-
- Fyll ut dette feltetLegg til et navnLås opp for å se dine lagrede betalingskort
- Sikre dine betalingskort
-
Sikre dine lagrede betalingsmåter
- Konfigurer en PIN-kode, et passord eller et låsemønster for å beskytte de lagrede betalingskortene dine om noen andre skulle få tak i enheten din.
-
Konfigurer en PIN-kode, et passord eller et låsemønster for å beskytte dine lagrede betalingsmåter om noen andre skulle få tak i enheten din.Konfigurer nå
@@ -1973,9 +1968,6 @@
Lås opp enheten din
-
- Lås opp for å bruke lagret betalingskortinformasjon
-
Lås opp for å bruke lagrede betalingsmåter
@@ -1984,12 +1976,6 @@
Rediger adresseBehandle adresser
-
- Fornavn
-
- Mellomnavn
-
- EtternavnNavn
@@ -2015,8 +2001,6 @@
Slett adresse
-
- Er du sikker på at du vil slette denne adressen?Slette denne adressen?
@@ -2117,49 +2101,29 @@
SlettRediger
-
- Er du sikker på at du ønsker å slette denne innloggingen?Er du sikker på at du ønsker å slette dette passordet?SlettAvbryt
-
- InnloggingsalternativerPassordalternativer
-
- Det redigerbare tekstfeltet for innloggingens nettadresse.Det redigerbare tekstfeltet for nettstedsadressen.
-
- Det redigerbare tekstfeltet for innloggingens brukernavn.Det redigerbare tekstfeltet for brukernavnet.
- Det redigerbare tekstfeltet for innloggingens passord.
-
Det redigerbare tekstfeltet for passordet.
-
- Lagre endringer for innlogging.Lagre endringer.
-
- RedigerRediger passord
-
- Legg til ny innloggingLegg til passord
-
- Passord krevesSkriv inn et passord
- Brukernavn påkrevd
-
Skriv inn et brukernavnServernavn påkrevd
@@ -2508,6 +2472,8 @@
Ikke nåVis original
+
+ Original uoversatt side lastet innFerdig
@@ -2564,6 +2530,9 @@
Lukk oversettelsesarket
+
+ Noen innstillinger er midlertidig utilgjengelige.
+
Oversettelser
@@ -2588,6 +2557,9 @@
Velg et språk for å behandle innstillinger for «oversett alltid» og «oversett aldri».
+
+ Kunne ikke laste inn språk. Prøv igjen senere.
+
Tilby å oversette (standard)
@@ -2610,6 +2582,8 @@
Fjern %1$s
+
+ Kunne ikke laste inn nettsteder. Prøv igjen senere.Vil du slette %1$s?
@@ -2687,13 +2661,18 @@
Naviger tilbake
+
+ Åpne feilsøkingsskuffen
+
FaneverktøyAntall faner
- Aktiv
+ Aktiv
+
+ AktivInaktiv
@@ -2704,6 +2683,16 @@
Verktøy for å lage fanerAntall faner som skal opprettes
+
+ Tekstfeltet er tomt
+
+ Angi bare positive heltall
+
+ Skriv inn et tall større enn null
+
+ Overskredet det maksimale antallet faner (%1$s) som kan genereres i én operasjonLegg til aktive faner
@@ -2711,6 +2700,39 @@
Legg til private faner
+
+
+
+ Fortsett
+
+ Gjennomfør denne undersøkelsen
+
+ Personvernbestemmelser
+
+ Send
+
+ Lukk
+
+ Takk for tilbakemeldingen!
+
+ Veldig fornøyd
+
+ Fornøyd
+
+ Nøytral
+
+ Misfornøyd
+
+ Veldig misfornøyd
+
+
+
+ Åpen undersøkelse
+
+ Lukk undersøkelse
+
+ Lukk
+
Innlogginger
diff --git a/mobile/android/fenix/app/src/main/res/values-night/colors.xml b/mobile/android/fenix/app/src/main/res/values-night/colors.xml
index 2b7178b3d2..228a8df4af 100644
--- a/mobile/android/fenix/app/src/main/res/values-night/colors.xml
+++ b/mobile/android/fenix/app/src/main/res/values-night/colors.xml
@@ -26,11 +26,11 @@
@color/photonYellow70A77
- @color/photonGreen80
+ @color/photonGreen80
- @color/photonPink80
+ @color/photonPink80
- @color/photonBlue50A80
+ @color/photonBlue50@color/photonDarkGrey80
@@ -40,7 +40,7 @@
@color/photonViolet60A50
- @color/photonLightGrey30
+ @color/photonDarkGrey05@color/photonDarkGrey10
@@ -48,11 +48,11 @@
@color/photonYellow40A41
- @color/photonGreen70
+ @color/photonGreen70
- @color/photonPink70A69
+ @color/photonPink70A69
- @color/photonBlue30
+ @color/photonBlue60@color/photonLightGrey05
@@ -78,9 +78,9 @@
@color/photonLightGrey05A40
- @color/photonRed20
+ @color/photonRed20
- @color/photonRed70
+ @color/photonRed20@color/photonViolet20
@@ -94,7 +94,7 @@
@color/photonLightGrey05A40
- @color/photonDarkGrey90
+ @color/photonLightGrey05@color/photonLightGrey05
@@ -117,9 +117,9 @@
@color/photonBlue30@color/photonLightGrey05
- @color/photonRed20
+ @color/photonRed20
- @color/photonRed70
+ @color/photonRed20@color/photonViolet20@color/photonBlue20@color/photonPink20
@@ -128,7 +128,7 @@
@color/photonLightGrey05
- @color/photonDarkGrey90
+ @color/photonLightGrey05@color/photonLightGrey05
@@ -149,7 +149,7 @@
@color/photonLightGrey05A40
- @color/photonRed40
+ @color/photonRed20@color/photonDarkGrey60
diff --git a/mobile/android/fenix/app/src/main/res/values-nl/strings.xml b/mobile/android/fenix/app/src/main/res/values-nl/strings.xml
index 3277940ff0..8d3f1fd0b8 100644
--- a/mobile/android/fenix/app/src/main/res/values-nl/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-nl/strings.xml
@@ -204,6 +204,10 @@
Add-onsExtensies
+
+ Extensies beheren
+
+ Meer extensies ontdekkenAccountinformatie
@@ -222,6 +226,8 @@
Openen in gewoon tabbladToevoegen aan startscherm
+
+ Toevoegen aan startscherm…Installeren
@@ -233,9 +239,13 @@
Pagina vertalen
+ In collectie opslaan…
+
In collectie opslaanDelen
+
+ Delen…Openen in %1$s
@@ -290,6 +300,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Opslaan
+
+ Bladwijzer voor deze pagina maken
+
+ Bladwijzer bewerken
+
+ Opslaan als PDF…
+
+ Lezerweergave inschakelen
+
+ Lezerweergave uitschakelen
+
+ Pagina vertalen…
+
+ Vertaald naar %1$s
+
+ Afdrukken…
+
Geen extensies hier
@@ -387,8 +415,6 @@
Firefox-privacyverklaring
-
- Lees meer in onze privacyverklaringWe houden u graag veiligTaal
- Vertaling
+ Vertaling
+
+ VertalingenGegevenskeuzes
@@ -670,10 +698,6 @@
VereistOptioneel
-
- Websitegegevens lezen en wijzigen
-
- Website verwijderenToestaan voor alle websites
@@ -800,8 +824,6 @@
GeschiedenisBladwijzers
-
- AanmeldingenWachtwoorden
@@ -828,8 +850,6 @@
and the third is the device model. -->
%1$s op %2$s %3$s
-
- CreditcardsBetalingsmethoden
@@ -845,6 +865,14 @@
Tabblad van %s
+
+
+ %1$s-tabbladen gesloten: %2$d
+
+ Onlangs gesloten tabbladen bekijken
+
Uitzonderingen
@@ -1776,13 +1804,9 @@
U kunt deze website eenvoudig aan het startscherm van uw apparaat toevoegen, om zo direct toegang te hebben en sneller te navigeren met een app-achtige ervaring.
-
- Aanmeldingen en wachtwoordenWachtwoorden
- Aanmeldingen en wachtwoorden opslaan
-
Wachtwoorden opslaanVragen om op te slaan
@@ -1797,46 +1821,27 @@
Gebruikersnamen en wachtwoorden in andere apps op uw apparaat invullen.
-
- Aanmelding toevoegen
-
Wachtwoord toevoegen
-
- Aanmeldingen synchroniserenWachtwoorden synchroniseren
-
- Aanmeldingen op apparaten synchroniserenWachtwoorden synchroniseren tussen apparaten
-
- Opgeslagen aanmeldingenOpgeslagen wachtwoorden
- De aanmeldingen die u opslaat of synchroniseert met %s worden hier getoond.
-
De wachtwoorden die u opslaat of synchroniseert met %s zullen hier worden vermeld. Alle wachtwoorden die u opslaat, zijn versleuteld.
-
- Meer info over Sync.Meer info over synchronisatieUitzonderingen
-
- Niet-opgeslagen aanmeldingen en wachtwoorden worden hier weergegeven.%s zal geen wachtwoorden voor de hier vermelde websites opslaan.
-
- Aanmeldingen en wachtwoorden worden voor deze websites niet opgeslagen.%s zal geen wachtwoorden voor deze websites opslaan.Alle uitzonderingen verwijderen
-
- Aanmeldingen zoekenWachtwoorden zoeken
@@ -1865,17 +1870,11 @@
Wachtwoord tonenWachtwoord verbergen
-
- Ontgrendel om uw opgeslagen aanmeldingen te bekijkenOntgrendel om uw opgeslagen wachtwoorden te bekijken
- Beveilig uw aanmeldingen en wachtwoorden
-
Beveilig uw opgeslagen wachtwoorden
- Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen aanmeldingen en wachtwoorden te beschermen tegen toegang als iemand anders uw apparaat heeft.
-
Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen wachtwoorden te beschermen tegen toegang als iemand anders uw apparaat heeft.Later
@@ -1892,8 +1891,6 @@
Naam (A-Z)Laatst gebruikt
-
- Menu Aanmeldingen sorterenWachtwoordmenu sorteren
@@ -1903,41 +1900,27 @@
Automatisch invullenAdressen
-
- CreditcardsBetalingsmethoden
- Kaarten opslaan en automatisch invullen
-
Betalingsmethoden opslaan en invullen
-
- Gegevens zijn versleuteld%s versleutelt alle betalingsmethoden die u opslaatKaarten synchroniseren tussen apparatenKaarten synchroniseren
-
- Creditcard toevoegenKaart toevoegen
-
- Opgeslagen kaarten beherenKaarten beherenAdres toevoegenAdressen beheren
-
- Adressen opslaan en automatisch invullenAdressen opslaan en invullen
-
- Informatie zoals nummers, e-mail- en verzendadressen toevoegenInclusief telefoonnummers en e-mailadressen
@@ -1961,8 +1944,6 @@
Kaart verwijderen
- Weet u zeker dat u deze creditcard wilt verwijderen?
-
Kaart verwijderen?Verwijderen
@@ -1976,24 +1957,15 @@
Opgeslagen kaarten
-
- Voer een geldig creditcardnummer in
-
Voer een geldig kaartnummer in
-
- Vul dit veld inVoeg een naam toeOntgrendel om uw opgeslagen kaarten te bekijken
- Beveilig uw creditcards
-
Beveilig uw opgeslagen betalingsmethoden
- Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen creditcards te beschermen tegen toegang als iemand anders uw apparaat heeft.
-
Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen betalingsmethoden te beschermen tegen toegang als iemand anders uw apparaat heeft.Nu instellen
@@ -2002,9 +1974,6 @@
Ontgrendel uw apparaat
-
- Ontgrendelen om opgeslagen creditcardgegevens te gebruiken
-
Ontgrendel om opgeslagen betalingsmethoden te gebruiken
@@ -2013,12 +1982,6 @@
Adres bewerkenAdressen beheren
-
- Voornaam
-
- Tweede naam
-
- AchternaamNaam
@@ -2044,8 +2007,6 @@
Adres verwijderen
-
- Weet u zeker dat u dit adres wilt verwijderen?Dit adres verwijderen?
@@ -2144,49 +2105,29 @@
VerwijderenBewerken
-
- Weet u zeker dat u deze aanmelding wilt verwijderen?Weet u zeker dat u dit wachtwoord wilt verwijderen?VerwijderenAnnuleren
-
- AanmeldoptiesWachtwoordopties
-
- Het bewerkbare tekstveld voor het webadres van de aanmelding.Het bewerkbare tekstveld voor het websiteadres.
-
- Het bewerkbare tekstveld voor de gebruikersnaam van de aanmelding.Het bewerkbare tekstveld voor de gebruikersnaam.
- Het bewerkbare tekstveld voor het wachtwoord van de aanmelding.
-
Het bewerkbare tekstveld voor het wachtwoord.
-
- Wijzigingen aan aanmelding opslaan.Wijzigingen opslaan.
-
- BewerkenWachtwoord bewerken
-
- Nieuwe aanmelding toevoegenWachtwoord toevoegen
-
- Wachtwoord vereistVul een wachtwoord in
- Gebruikersnaam vereist
-
Vul een gebruikersnaam inHostnaam vereist
@@ -2537,6 +2478,8 @@
Niet nuOrigineel tonen
+
+ Oorspronkelijk onvertaalde pagina geladenGereed
@@ -2594,6 +2537,9 @@
Blad Vertalingen sluiten
+
+ Sommige instellingen zijn tijdelijk niet beschikbaar.
+
Vertalingen
@@ -2617,6 +2563,9 @@
Selecteer een taal om de voorkeuren ‘Altijd vertalen’ en ‘Nooit vertalen’ te beheren.
+
+ Kan talen niet laden. Probeer het later nog eens.
+
Aanbieden om te vertalen (standaard)
@@ -2639,6 +2588,8 @@
%1$s verwijderen
+
+ Kan websites niet laden. Probeer het later nog eens.%1$s verwijderen?
@@ -2716,13 +2667,18 @@
Terug bladeren
+
+ Debuglade openen
+
TabbladhulpmiddelenAantal tabbladen
- Actief
+ Actief
+
+ ActiefInactief
@@ -2733,6 +2689,16 @@
Hulpmiddel voor het aanmaken van tabbladenAantal aan te maken tabbladen
+
+ Tekstveld is leeg
+
+ Voer alleen positieve gehele getallen in
+
+ Voer een getal groter dan nul in
+
+ Het maximale aantal tabbladen (%1$s) dat in één bewerking kan worden aangemaakt is overschredenToevoegen aan actieve tabbladen
@@ -2749,11 +2715,11 @@
Privacyverklaring
- Indienen
+ Indienen
- Sluiten
+ Sluiten
- Bedankt voor uw feedback!
+ Bedankt voor uw feedback!Zeer tevreden
@@ -2765,6 +2731,14 @@
Zeer ontevreden
+
+
+ Enquête openen
+
+ Enquête sluiten
+
+ Sluiten
+
Aanmeldingen
diff --git a/mobile/android/fenix/app/src/main/res/values-nn-rNO/strings.xml b/mobile/android/fenix/app/src/main/res/values-nn-rNO/strings.xml
index a85ae3472e..928e6f2594 100644
--- a/mobile/android/fenix/app/src/main/res/values-nn-rNO/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-nn-rNO/strings.xml
@@ -51,12 +51,20 @@
- Nyleg lagra
+ Nyleg lagra
- Vis alle lagra bokmerke
+ Vis alle lagra bokmerke
- Fjern
+ Fjern
+
+
+
+ Bokmerke
+
+ Vis alle bokmerke
+
+ Fjern%1$s er produsert av Mozilla.
@@ -197,6 +205,10 @@
TilleggUtvidingar
+
+ Handsam utviding
+
+ Oppdag fleire utvidingarKontoinformasjon
@@ -215,18 +227,26 @@
Opne i vanlig faneLegg til på startskjermen
+
+ Legg til på startskjermen…InstallerSynkroniser på nyttFinn på sida
+
+ Finn på sida…Omset sida
+ Lagre i samling…
+
Lagre i samlingDel
+
+ Del…Opne i %1$s
@@ -258,11 +278,44 @@
Synkroniser passord, faner, og meir
+
+ Logg inn igjen for å synkronisere
+
+ Synkronisering sett på pauseNy privat fanePassord
+
+ Nytt i %1$s
+
+ Byt til datamaskinversjon
+
+ Verktøy
+
+ Lagre
+
+ Bokmerk denne sida
+
+ Rediger bokmerke
+
+ Lagre som PDF…
+
+
+ Slå på leservising
+
+ Slå av leservising
+
+ Omset sida…
+
+ Omset til %1$s
+
+ Skriv ut…
+
Ingen utvidingar her
@@ -359,10 +412,15 @@
Firefox personvernerklæring
-
- Les meir i personvernerklæringa vårVi vernar deg gjerne
+
+ Finn ut kvifor millionar likar Firefox
+
+ Sikker surfing med fleire val
+
+ Den ideelle nettlesaren vår hindrar selskap i å spore aktiviteten din i hemmelegheit på nettet.Meir enn 100 millionar menneske beskyttar personvernet sitt ved å velje ein nettleser som er støtta av ein ideell organisasjon.
@@ -385,6 +443,12 @@
Logg innIkkje no
+
+ Varsel gjer deg tryggare med Firefox
+
+ Send faner trygt mellom einingane dine og oppdag andre personvernfunksjonar i Firefox.Slå på varsel
@@ -437,6 +501,8 @@
SøkjemotorarForslag frå søkjemotorar
+
+ Innstillingar for adresselinjaAdresselinje - Firefox forslag
@@ -553,6 +619,10 @@
Kople til igjen for å halde fram synkroniseringaSpråk
+
+ Omsetting
+
+ OmsettingarDataval
@@ -611,6 +681,8 @@
UtvidingarInstaller utviding frå fil
+
+ Installer utviding frå filVarsel
@@ -623,9 +695,18 @@
Påkravd
+
+ Valfri
+
+ Tillat for alle nettstadar
+
+ Viss du stolar på denne utvidinga, kan du gje henne løyve på kvar nettstad.
+
Tilpassa tilleggssamling
+
+ Tilpassa utvidings-samlingOK
@@ -637,11 +718,16 @@
Tilleggssamling endra. Avsluttar applikasjonen for å bruke endringar…
+
+ Utvidingssamling endra. Avsluttar applikasjonen for å leggje til endringar…
+
Hopp inn igjen
- Nylege bokmerke
+ Nylege bokmerke
+
+ BokmerkeNyleg besøkte
@@ -693,22 +779,38 @@
Nye utvidingar tilgjengelege no
+
+ Nye utvidingar tilgjengelege noSjekk ut 100+ nye utvidingar som lèt deg gjere Firefox til din eigen.Utforsk utvidingar
+
+ Utforsk utvidingar
+
Tillegg er mellombels deaktivert
+
+ Utvidinga er mellombels deaktivertEitt eller fleire tillegg slutta å fungere, noko som gjorde systemet ditt ustabilt. %1$s prøvde utan hell å starte tillegget/tillegga på nytt.\n\nTillegg vil ikkje bli starta på nytt under gjeldande økt.\n\nDersom du fjernar eller deaktiverer tillegg, kan dette løyse problemet.
+
+ Ei eller flere utvidingar slutta å fungere, noko som gjorde systemet ditt ustabilt. %1$s prøvde utan hell å starte utvidinga(ne) på nytt.\n\nUtvidingane vil ikkje bli starta på nytt under gjeldande økt.\n\nViss du fjernar eller deaktiverer utvidingar, kan dette løyse problemet.Prøv å starte tillegga på nytt
+
+ Prøv å starte utvidingar på nyttHald fram med deaktiverte tillegg
+
+ Hald fram med utvidingar deaktiverte
+
Handsam kontoen
@@ -722,8 +824,6 @@
HistorikkBokmerke
-
- InnloggingarPassord
@@ -750,8 +850,6 @@
and the third is the device model. -->
%1$s på %2$s %3$s
-
- BetalingskortBetalingsmåtar
@@ -767,6 +865,15 @@
Fane frå %s
+
+
+ %1$s lét att %2$d faner
+
+
+ Vis nyleg attlatne faner
+
Unntak
@@ -1347,6 +1454,8 @@
Late att private faner?
+ Trykk eller sveip dette varselet for å late att private faner.
+
Marknadsføring
@@ -1700,13 +1809,9 @@
Du kan enkelt leggje til denne nettstaden på startskjermen til eininga for å, med ein gong, få tilgang og surfe raskare med ei app-liknande oppleving.
-
- Innloggingar og passordPassord
- Lagre innloggingar og passord
-
Lagre passordSpør om å lagre
@@ -1723,40 +1828,27 @@
Fyll inn brukarnamn og passord i andre appar på eininga di.
-
- Legg til innlogging
-
Legg til passord
-
- Synkroniser innloggingarSynkroniser passord
-
- Synkroniser innloggingar på tvers av einingarSynkroniser passord på tvers av einingar
-
- Lagra innloggingarLagra passord
- Innloggingane du lagrar eller synkroniserer til %s vil visast her.
-
- Les meir om Sync.
+ Passorda du lagrar eller synkroniserer med %s vil bli oppførte her. Alle passorda du lagrar er krypterte.Les meir om synkroniseringUnntak
-
- Innloggingar og passord som ikkje er lagra vil visast her.
-
- Innloggingar og passord vil ikkje bli lagra for desse nettstadane.
+
+ %s vil ikkje lagre passord for nettstadar som er oppførte her.
+
+ %s vil ikkje lagre passord for desse nettstadane.Slett alle unntak
-
- Søk innloggingarSøk etter passord
@@ -1786,12 +1878,12 @@
Vis passordGøym passord
-
- Lås opp for å sjå dei lagra innloggingane dine
+
+ Lås opp for å sjå dei lagra passorda dine
- Gjer innloggingane og passorda dine trygge
+ Sikre dei lagra passorda dine
- Lag ein PIN-kode, eit passord eller eit låsemønster for å hindre at andre får tilgang dei lagra innloggingane og passorda dine, dersom dei har tilgang til eininga di.
+ Konfigurer ein PIN-kode, eit passord eller eit låsemønster for å beskytte dei lagra passorda dine om nokon andre skulle få tak i eininga di.Seinare
@@ -1807,8 +1899,6 @@
Namn (A-Å)Sist brukt
-
- Sorter inloggningsmenyenSorter passord-menyen
@@ -1818,27 +1908,19 @@
AutofyllAdresser
-
- BetalingskortBetalingsmåtar
- Lagre og fyll ut kort automatisk
-
Lagre og fyll inn betalingsmåtar
-
- Data er kryptert
+
+ %s krypterer alle betalingsmåtar du lagrarSynkroniser kort på tvers av einingarSynkroniser kort
-
- Legg til betalingskortLegg til kort
-
- Handsam lagra kortHandsam kort
@@ -1846,12 +1928,8 @@
Handsam adresser
-
- Lagre og fyll ut adresser automatiskLagre og fyll ut adresser
-
- Inkluderer informasjon som telefonnummer, e-post og leveringsadresserInkluderer telefonnummer og e-postadresser
@@ -1875,8 +1953,6 @@
Slett kort
- Er du sikker på at du vil slette dette bankkortet?
-
Slette kort?Slett
@@ -1890,21 +1966,16 @@
Lagra bankkort
-
- Skriv inn eit gyldig betalingskortnummer
-
Skriv inn eit gyldig kortnummer
-
- Fyll ut dette feltetLegg til eit namnLås opp for å sjå lagra betalingskort
- Sikre betalingskorta dine
+ Sikre dei lagra betalingsmåtane dine
- Konfigurer eit låsemønster for eininga, PIN, eller passord, for å beskytte dei lagra betalingskorta dine om nokon andre skulle få tak i eininga di.
+ Konfigurer ein PIN-kode, eit passord eller eit låsemønster for å beskytte dei lagra betalingsmåtane dine om nokon annan skulle få tak i eininga di.Konfigurer no
@@ -1912,21 +1983,14 @@
Lås opp eininga di
-
- Lås opp for å bruke lagra betalingskortinformasjon
-
+
+ Lås opp for å bruke lagra betalingsmåtarLegg til adresseRediger adresseHandsam adresser
-
- Fornamn
-
- Mellomnamn
-
- EtternamnNamn
@@ -1952,8 +2016,6 @@
Slett adresse
- Er du sikker på at du vil slette denne adressa?
-
Slette denne adressa?Slett
@@ -2055,41 +2117,29 @@
SlettRediger
-
- Er du sikker på at du ønskjer å slette denne innlogginga?
+
+ Er du sikker på at du ønskjer å slette dette passordet?SlettAvbryt
-
- InnloggingsalternativPassordalternativ
-
- Det redigerbare tekstfeltet for innloggings-nettadressa.
-
- Det redigerbare tekstfeltet for innloggings-brukarnamnet.
+
+ Det redigerbare tekstfeltet for nettstadadressa.
+
+ Det redigerbare tekstfeltet for brukarnamnet.
- Det redigerbare tekstfeltet for innloggings-passordet.
-
- Lagre endringar for innlogging.
+ Det redigerbare tekstfeltet for passordet.Lagre endringar.
-
- RedigerRediger passord
-
- Legg til ny innloggingLegg til passord
-
- Passord påkravdSkriv inn passord
- Brukarnamn påkravd
-
Skriv inn eit brukarnamnVertsnamn påkravd
@@ -2192,6 +2242,9 @@
Søk med %s
+
+
+ Endre standardnettlesarVel at lenker frå nettstadar, e-postmeldingar og meldingar skal opnast automatisk i Firefox.
@@ -2342,6 +2395,10 @@
Med krafta i %1$s frå Mozilla hjelper vi deg med å unngå einsidige og ikkje-truverdige vurderingar. AI-modellen vår vert alltid forbetra for å beskytte deg når du handlar. %2$sLes meir
+
+ Ved å velje «Ja, prøv det» godtek du %1$s sine %2$s og %3$s sine %4$s.
+
+ Ved å velje «Ja, prøv det» godtek du %1$s sine %2$s og %3$s sine %4$s.peronvernerklæring
@@ -2413,16 +2470,28 @@
Omsetje denne sida?
+
+ Sida er omsett frå %1$s til %2$s
+
+ Prøv private omsettingar i %1$s
+
+ Av omsyn til personvernet ditt forlét aldri omsettingar eininga di. Nye språk og forbetringar kjem snart! %1$sLes meirOmset fråOmset til
+
+ Prøv eit anna kjeldespråkIkkje noVis original
+
+ Original ikkje-omsett side lasta innFerdig
@@ -2438,6 +2507,10 @@
Vel eit språkDet oppstod eit problem med å omsetje. Prøv på nytt.
+
+ Klarte ikkje å laste inn språk. Sjekk Internett-tilkoplinga di og prøv igjen.
+
+ Beklagar, vi stør ikkje %1$s enno.Les meir
@@ -2445,9 +2518,18 @@
Omset…
+
+ Last ned språk i datasparemodus (%1$s)?
+
+
Innstillingar for omsetjing
+
+ Innstillingar for omsettingTilby alltid å omsetje
@@ -2465,12 +2547,20 @@
Om omsetjingar i %1$s
+
+ Lat att omsettingsarket
+
+
+ Nokre innstillingar er mellombels utilgjengelege.
+
OmsetjingarTilby å omsetje når det er muleg
+
+ Last alltid ned språk i datasparemodusInnstillingar for omsetjing
@@ -2487,6 +2577,9 @@
Vel eit språk for å handsame innstillingar for «omset alltid» og «omset aldri».
+
+ Klarte ikkje å laste inn språk. Prøv igjen seinare.
+
Tilby å omsetje (standard)
@@ -2510,6 +2603,8 @@
Fjern %1$s
+
+ Klarte ikkje å laste inn nettstadar. Prøv igjen seinare.Vil du slette %1$s?
@@ -2551,11 +2646,28 @@
The first parameter is the name of the language, for example, "Spanish" and the second parameter is the size in kilobytes or megabytes of the language file. -->
Slett %1$s (%2$s)?
+
+ Viss du slettar dette språket, vil %1$s laste ned delar av språk til snøgglageret ditt medan du omset.
+
+ Slette alle språk (%1$s)?
+
+ Viss du slettar alle språk, vil %1$s laste ned delar av språk tilsnøgglageret ditt medan du omset.SlettAvbryt
+
+ Laste ned medan du er i datasparemodus (%1$s)?
+
+ Vi lastar ned delvise språk til snøgglageret ditt for å halde omsettingar private.
+
+ Vi lastar ned delvise språk for å halde omsettingar private.Last alltid ned i datasparemodus
@@ -2571,13 +2683,18 @@
Naviger tilbake
+
+ Opne feilsøkingsskuffa
+
FaneverktøyAntal faner
- Verksam
+ Verksam
+
+ AktivUverksam
@@ -2588,6 +2705,16 @@
Verktøy for å lage fanerTal på faner som skal opprettast
+
+ Text field is empty
+
+ Skriv inn berre positive heiltall
+
+ Skriv inn eit tal større enn null
+
+ Overskreid det maksimale talet på faner (%1$s) som kan genererast i éin operasjonLegg til i verksame faner
@@ -2599,16 +2726,43 @@
Hald fram
+
+ Ver med i denne undersøkingaPersonvernerklæring
- Send inn
+ Send inn
- Lat att
+ Lat att
- Takk for tilbakemeldinga di!
+ Takk for tilbakemeldinga di!
+
+
+ Veldig fornøgd
+
+ Fornøgd
+
+ Nøytral
+
+ Misfornøgd
+
+ Veldig misfornøgd
+
+
+
+ Opne undersøking
+
+ Lat att undersøking
+
+ Lat attInnloggingar
-
+
+ Gjeldande domene: %s
+
+ Legg til ei falsk innlogging for dette domenet
+
+ Slett innlogging med brukarnamn %s
+
diff --git a/mobile/android/fenix/app/src/main/res/values-oc/strings.xml b/mobile/android/fenix/app/src/main/res/values-oc/strings.xml
index dadbc407db..93e80beb14 100644
--- a/mobile/android/fenix/app/src/main/res/values-oc/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-oc/strings.xml
@@ -48,12 +48,20 @@
- Salvats recentament
+ Salvats recentament
- Afichar totes los marcapaginas enregistrats
+ Afichar totes los marcapaginas enregistrats
- Levar
+ Levar
+
+
+
+ Marcapaginas
+
+ Afichar totes los marcapaginas
+
+ Suprimir%1$s es produch per Mozilla.
@@ -191,6 +199,10 @@
ModulsExtensions
+
+ Gerir las extensions
+
+ Descobrir mai d’extensionsInformacion compte
@@ -209,18 +221,26 @@
Dobrir dins un onglet classicApondre a l’ecran d’acuèlh
+
+ Apondre a l’ecran d’acuèlh…InstallarTornar sincronizarRecercar dins la pagina
+
+ Recercar dins la pagina…Traduire la pagina
+ Salvar a la colleccion…
+
Salvar a la colleccionPartejar
+
+ Partejar…Dobrir amb %1$s
@@ -262,6 +282,34 @@
Senhals
+
+ Novetats dins %1$s
+
+ Passar en version ordenador
+
+ Aisinas
+
+ Enregistrar
+
+ Marcar aquesta pagina
+
+ Modificar lo marcapagina
+
+ Enregistrar en PDF…
+
+ Passar a la vista lectura
+
+ Quitar lo mòde lectura
+
+ Traduire la pagina…
+
+ Traduch en %1$s
+
+ Imprimir…
+
Cap d’extension aquí
@@ -358,8 +406,6 @@
Politica de confidencialitat de Firefox
-
- Ne saber mai tocant nòstra politica de confidencialitatNos impòrta vòstra vida privadaLenga
+
+ Traduccion
+
+ TraduccionsDonadas collectadas
@@ -641,10 +691,6 @@
RequesidaFacultativa
-
- Consultar e modificar las donadas de sites web
-
- Suprimir lo site webAutorizar per totes los sites
@@ -675,7 +721,9 @@
Tornar a aqueste onglet
- Marcats recentament
+ Marcats recentament
+
+ MarcapaginasVisitats fa res
@@ -772,8 +820,6 @@
IstoricMarcapaginas
-
- IdentificantsSenhals
@@ -802,8 +848,6 @@
and the third is the device model. -->
%1$s sus %2$s %3$s
-
- Cartas de crèditMetòdes de pagament
@@ -819,6 +863,14 @@
Onglet de %s
+
+
+ %2$d onglets tampats de %1$s
+
+ Veire los onglets tampats recentament
+
Excepcions
@@ -1766,13 +1818,9 @@
Podètz facilament apondre aqueste site a l’ecran d’acuèlh de vòstre periferic per i accedir dirèctament e i navegar coma se foguèsse una aplicacion.
-
- Identificants e senhalsSenhals
- Salvar los identificants e senhals
-
Salvar senhalsDemandar per salvar
@@ -1789,47 +1837,28 @@
Emplena los noms d’utilizaires e los senhals d’autres aplicacions sus vòstre periferic.
-
- Apondre un identificant
-
Apondre un senhal
-
- Sincronizar los identificantsSincronizar los senhals
-
- Sincronizar los identificants entre totes los perifericsSincronizar los senhals entre los periferics
-
- Identificants salvatsSenhals salvats
- Aquí se mòstran los identificants que salvatz o sincronizatz amb %s.
-
Los senhals que salvatz o sincronizatz amb %s seràn listats aquí. Totes los senhals qu’enregistratz son chifrats.
-
- Per ne saber mai sus Sync.Per ne saber mai sus syncExcepcions
-
- Los identificants e senhals pas salvats seràn mostrats aquí.%s enregistrarà pas los senhals pels sites listats aicí.
-
- Los identificants e senhals seràn pas salvats per aquestes sites.%s enregistrarà pas los senhals per aquestes sites.Suprimir totas las excepcions
-
- Recercar d’identificantsRecercar de senhals
@@ -1859,17 +1888,11 @@
Amagar lo senhal
-
- Desblocatz per veire los identificants enregistratsDesblocatz per veire los senhals salvats
- Protegissètz vòstres identificants e senhals
-
Securizatz los senhals salvats
- Configuratz un esquèma de verrolhatge, un còdi PIN o un senhal per protegir vòstres identificants de connexion e senhals enregistrats se per cas qualqu’un accedisca a vòstre periferic.
-
Configuratz un esquèma de desverrolhatge, un còdi PIN o un senhal per protegir vòstres senhals salvats se per cas qualqu’un accedisca a vòstre aparelh.Mai tard
@@ -1886,9 +1909,6 @@
Darrièra utilizacion
-
- Menú per triar los identificants
-
Menú de tria dels senhals
@@ -1897,42 +1917,28 @@
Emplenament automaticAdreças
-
- Cartas de crèditMetòdes de pagament
- Salvar e completar automaticament las cartas
-
Enregistrar e entresenhar los metòdes de pagament
-
- Donadas chifradas%s chifra totes los metòdes de pagament qu’enregistratzSincronizar las cartas entre los perifericsSincronizar las cartas
-
- Apondre una cartas de crèditApondre una carta
-
- Gerir las cartas enregistradasGerir las cartasApondre una adreçaGerir las adreças
-
- Salvar e completar automaticament las adreçasSalvar e emplenar automaticament las adreças
-
- Inclutz las informacions coma los numèros, las adreças electronicas e las adreças de liurasonIncluses los numèros de telefòn e las adreças electronicas
@@ -1956,8 +1962,6 @@
Suprimir la carta
- Volètz vertadièrament suprimir aquesta carta bancària ?
-
Suprimir la carta ?Suprimir
@@ -1971,25 +1975,16 @@
Cartas enregistradas
-
- Picatz un numèro de carta de crèdit valid
-
Picatz un numèro de carta valid
-
- Completatz aqueste campApondre un nomDesblocatz per veire las cartas enregistradas
-
- Securizatz vòstras cartas de crèditSecurizatz los metòdes de pagament enregistrats
- Configuratz un esquèma de verrolhatge, un còdi PIN o un senhal per protegir vòstres identificants de cartas de crèdit enregistrats se per cas qualqu’un accedisca a vòstre periferic.
-
Configuratz un esquèma de desverrolhatge, un còdi PIN o un senhal per protegir vòstres mejans de pagament se per cas qualqu’un accedisca a vòstre aparelh.Configurar ara
@@ -1998,9 +1993,6 @@
Desverrolhatz lo periferic
-
- Desverrolhatz per utilizar las informacions de cartas de crèdit enregistradas
-
Desblocatz per utilizar de metòdes de pagament enregistrats
@@ -2009,12 +2001,6 @@
Modificar l’adreçaGestion de las adreças
-
- Pichon nom
-
- Segond pichon nom
-
- Nom d’ostalNom
@@ -2040,8 +2026,6 @@
Suprimir l’adreça
-
- Volètz vertadièrament suprimir aquesta adreça ?Suprimir aquesta adreça ?
@@ -2142,8 +2126,6 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox&
SuprimirModificar
-
- Volètz vertadièrament suprimir aqueste identificant ?Volètz vertadièrament suprimir aqueste senhal ?
@@ -2151,41 +2133,23 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox&
Anullar
-
- Opcions de l’identificantOpcions de senhal
-
- Lo camp de tèxt modificable per l’adreça web de l’identificant.Lo camp de tèxt modificable per l’adreça del site web.
-
- Lo camp de tèxt modificable pel nom d’utilizaire de l’identificant.Lo camp de tèxt modificable pel nom d’utilizaire.
- Lo camp de tèxt modificable pel senhal de l’identificant.
-
Lo camp de tèxt modificable pel senhal.
-
- Enregistratz las modificacions de l’identificant.Enregistrar las modificacions.
-
- ModificarModificar lo senhal
-
- Apondre un identificant novèlApondre un senhal
-
- Senhal requesitPicar lo senhal
- Lo nom d’utilizaire es obligatòri
-
Picar un nom d’utilizaireLo nom d’òste es obligatòri
@@ -2535,6 +2499,8 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox&
Pas araVeire la pagina originala
+
+ Pagina originala non traducha cargadaAcabat
@@ -2718,13 +2684,18 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox&
Tornar
+
+ Dobrir lo panèl de desvolopament
+
Aisinas d’ongletNombre d’onglets
- Actius
+ Actius
+
+ ActiuInactius
@@ -2742,6 +2713,31 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox&
Apondre als onglets privats
+
+
+
+ Contunhar
+
+ Participar al sondatge
+
+ Politica de confidencialitat
+
+ Mandar
+
+ Tampar
+
+ Mercés per vòstre retorn !
+
+ Plan satisfach
+
+ Satisfach
+
+ Indiferent
+
+ Insatisfach
+
+ Plan insatisfach
+
Identificants
diff --git a/mobile/android/fenix/app/src/main/res/values-pa-rIN/strings.xml b/mobile/android/fenix/app/src/main/res/values-pa-rIN/strings.xml
index 2f5f2c0153..7991883f6d 100644
--- a/mobile/android/fenix/app/src/main/res/values-pa-rIN/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-pa-rIN/strings.xml
@@ -205,6 +205,10 @@
ਐਡ-ਆਨਇਕਸਟੈਨਸ਼ਨਾਂ
+
+ ਇਕਸਟੈਨਸ਼ਨਾਂ ਦਾ ਇੰਤਜ਼ਾਮ
+
+ ਹੋਰ ਇਕਸਟੈਨਸ਼ਨਾਂ ਲੱਭੋਖਾਤਾ ਜਾਣਕਾਰੀ
@@ -223,6 +227,8 @@
ਰੈਲੂਲਰ ਟੈਬ ਵਿੱਚ ਖੋਲ੍ਹੋਮੁੱਖ ਸਕਰੀਨ ‘ਤੇ ਜੋੜੋ
+
+ …ਮੁੱਖ ਸਕਰੀਨ ‘ਤੇ ਜੋੜੋਇੰਸਟਾਲ ਕਰੋ
@@ -235,9 +241,13 @@
ਸਫ਼ੇ ਦਾ ਉਲੱਥਾ ਕਰੋ
+ …ਭੰਡਾਰ ਵਿੱਚ ਸੰਭਾਲੋ
+
ਭੰਡਾਰ ‘ਚ ਸੰਭਾਲੋਸਾਂਝਾ ਕਰੋ
+
+ …ਸਾਂਝਾ ਕਰੋ%1$s ‘ਚ ਖੋਲ੍ਹੋ
@@ -291,6 +301,25 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
ਸੰਭਾਲੋ
+
+ ਇਹ ਸਫ਼ੇ ਨੂੰ ਬੁੱਕਮਾਰਕ ਕਰੋ
+
+ ਬੁੱਕਮਾਰਕ ਨੂੰ ਸੋਧੋ
+
+ …PDF ਵਜੋਂ ਸੰਭਾਲੋ
+
+ ਪੜ੍ਹਨ ਝਲਕ ਨੂੰ ਚਾਲੂ ਕਰੋ
+
+ ਪੜ੍ਹਨ ਝਲਕ ਨੂੰ ਬੰਦ ਕਰੋ
+
+ …ਸਫ਼ੇ ਦਾ ਉਲੱਥਾ ਕਰੋ
+
+
+ %1$s ਵਿੱਚ ਉਲੱਥਾ ਕੀਤਾ
+
+ …ਪਰਿੰਟ ਕਰੋ
+
ਇੱਥੇ ਕੋਈ ਇਕਸਟੈਨਸ਼ਨ ਨਹੀਂ ਹੈ
@@ -388,8 +417,6 @@
Firefox ਪਰਦੇਦਾਰੀ ਸੂਚਨਾ
-
- ਸਾਡੀ ਪਰਦੇਦਾਰੀ ਸੂਚਨਾ ਵਿੱਚ ਹੋਰ ਜਾਣਕਾਰੀ ਲਵੋਅਸੀਂ ਤੁਹਾਨੂੰ ਸੁਰੱਖਿਅਤ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹਾਂਭਾਸ਼ਾ
- ਉਲੱਥਾ
+ ਉਲੱਥਾ
+
+ ਅਨੁਵਾਦਡਾਟਾ ਚੋਣਾਂ
@@ -675,10 +704,6 @@
ਲੋੜੀਂਦਾਚੋਣਵਾਂ
-
- ਵੈੱਬਸਾਈਟ ਡਾਟਾ ਪੜ੍ਹਨ ਅਤੇ ਬਦਲਣ
-
- ਵੈੱਬਸਾਈਟ ਨੂੰ ਹਟਾਉਣਸਭ ਸਾਈਟਾਂ ਲਈ ਮਨਜ਼ੂਰੀ
@@ -805,8 +830,6 @@
ਅਤੀਤਬੁੱਕਮਾਰਕ
-
- ਲਾਗਇਨਪਾਸਵਰਡ
@@ -834,8 +857,6 @@
and the third is the device model. -->
%2$s %3$s ਉੱਤੇ %1$s
-
- ਕਰੈਡਿਟ ਕਾਰਡਭੁਗਤਾਨ ਦੇ ਢੰਗ
@@ -851,6 +872,14 @@
%s ਤੋਂ ਟੈਬ
+
+
+ %1$s ਟੈਬਾਂ ਬੰਦ ਕੀਤੀਆਂ: %2$d
+
+ ਤਾਜ਼ਾ ਬੰਦ ਕੀਤੀਆਂ ਟੈਬਾਂ ਨੂੰ ਵੇਖੋ
+
ਛੋਟਾਂ
@@ -1787,13 +1816,9 @@
ਤੁਸੀਂ ਇਸ ਵੈੱਬਸਾਈਟ ਨੂੰ ਫ਼ੌਰੀ ਤੌਰ ਉੱਤੇ ਵਰਤਣ ਤੇ ਐਪ ਵਾਂਗ ਤੇਜ਼ ਬਰਾਊਜ਼ ਕਰਨ ਲਈ ਸੌਖੀ ਤਰ੍ਹਾਂ
ਮੁੱਖ ਸਕਰੀਨ ਉੱਤੇ ਸੌਖੀ ਤਰ੍ਹਾਂ ਜੋੜ ਸਕਦੇ ਹੋ।
-
- ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡਪਾਸਵਰਡ
- ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ ਸੰਭਾਲੋ
-
ਪਾਸਵਰਡਾਂ ਨੂੰ ਸੰਭਾਲੋ ਸੰਭਾਲਣ ਲਈ ਪੁੱਛੋ
@@ -1808,46 +1833,28 @@
ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਉੱਤੇ ਹੋਰ ਐਪਾਂ ਵਿੱਚ ਵਰਤੋਂਕਾਰ-ਨਾਂ ਅਤੇ ਪਾਸਵਰਡ ਭਰੋ।
-
- ਲਾਗਇਨ ਜੋੜੋਪਾਸਵਰਡ ਜੋੜੋ
-
- ਲਾਗਇਨ ਸਿੰਕ ਕਰੋਪਾਸਵਰਡ ਸਿੰਕ ਕਰੋ
-
- ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਲਾਗਇਨਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋਪਾਸਵਰਡ ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਸਿੰਕ ਕਰੋ
-
- ਸੰਭਾਲੇ ਹੋਏ ਲਾਗਇਨਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ
- ਤੁਹਾਡੇ ਵਲੋਂ ਸੰਭਾਲੇ ਲਾਗਇਨ ਜਾਂ %s ਨਾਲ ਸਿੰਕ ਕੀਤੇ ਇੱਥੇ ਵੇਖਾਏ ਜਾਣਗੇ।
-
ਤੁਹਾਡੇ ਵਲੋਂ %s ਵਿੱਚ ਸੰਭਾਲੇ ਜਾਂ ਸਿੰਕ ਕੀਤੇ ਪਾਸਵਰਡਾਂ ਨੂੰ ਇੱਥੇ ਦਿਖਾਇਆ ਜਾਵੇਗਾ। ਤੁਹਾਡੇ ਸਾਰੇ ਸੰਭਾਲੇ ਪਾਸਵਰਡ ਇੰਕ੍ਰਿਪਟ ਕੀਤੇ ਹੁੰਦੇ ਹਨ।
-
- ਸਿੰਕ ਬਾਰੇ ਹੋਰ ਜਾਣੋ।ਸਿੰਕ ਬਾਰੇ ਹੋਰ ਜਾਣੋਛੋਟਾਂ
-
- ਨਾ ਸੰਭਾਲੇ ਹੋਏ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡਾਂ ਨੂੰ ਇੱਥੇ ਸੰਭਾਲਿਆ ਜਾਵੇਗਾ।%s ਇੱਥੇ ਦਿੱਤੀਆਂ ਹੋਈਆਂ ਸਾਈਟਾਂ ਲਈ ਪਾਸਵਰਡ ਨਹੀਂ ਸੰਭਾਲੇਗਾ।
-
- ਇਹਨਾਂ ਸਾਈਟਾਂ ਲਈ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ ਨਹੀਂ ਸੰਭਾਲੇ ਜਾਣਗੇ।%s ਇਹਨਾਂ ਸਾਈਟਾਂ ਲਈ ਪਾਸਵਰਡ ਨਹੀਂ ਸੰਭਾਲੇਗਾ।ਸਾਰੀਆਂ ਛੋਟਾਂ ਹਟਾ ਦਿਓ
-
- ਲਾਗਇਨ ਖੋਜੋਪਾਸਵਰਡ ਖੋਜੋ
@@ -1876,17 +1883,11 @@
ਪਾਸਵਰਡ ਵੇਖਾਓਪਾਸਵਰਡ ਲੁਕਾਓ
-
- ਆਪਣੇ ਸੰਭਾਲੇ ਲਾਗਇਨ ਵੇਖਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ ਵੇਖਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ
- ਆਪਣੇ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ ਸੁਰੱਖਿਅਤ ਕਰੋ
-
ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ
- ਆਪਣੇ ਲਾਗਇਨਾਂ ਅਤੇ ਪਾਸਵਰਡਾਂ ਨੂੰ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਨੂੰ ਰੱਖਣ ਵਾਲੇ ਕਿਸੇ ਦੀ ਪਹੁੰਚ ਤੋਂ ਸੁਰੱਖਿਅਤ ਰੱਖਣ ਲਈ ਡਿਵਾਈਸ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈਟ ਅੱਪ ਕਰੋ।
-
ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡਾਂ ਨੂੰ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਉੱਤੇ ਕਿਸੇ ਹੋਰ ਵੱਲੋਂ ਪਹੁੰਚ ਕਰਨ ਤੋਂ ਬਚਾਉਣ ਤੋਂ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਡਿਵਾਈਸ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ।ਬਾਅਦ \'ਚ
@@ -1904,8 +1905,6 @@
ਨਾਂ (A-Z)ਆਖਰੀ ਵਰਤੋਂ
-
- ਲਾਗਇਨ ਲੜੀਬਧ ਮੇਨੂਪਾਸਵਰਡ ਮੇਨੂ ਨੂੰ ਲੜੀਬੱਧ ਕਰੋ
@@ -1915,40 +1914,26 @@
ਆਪੇ-ਭਰੋਸਿਰਨਾਵੇਂ
-
- ਕਰੈਡਿਟ ਕਾਰਡਭੁਗਤਾਨ ਦੇ ਢੰਗ
- ਕਾਰਡ ਸੰਭਾਲੋ ਅਤੇ ਆਪਣੇ-ਆਪ ਭਰੋ
-
ਭੁਗਤਾਨ ਦੇ ਢੰਗ ਸੰਭਾਲੋ ਅਤੇ ਭਰੋ
-
- ਡਾਟਾ ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ ਹੈ%s ਤੁਹਾਡੇ ਵਲੋਂ ਸੰਭਾਲੇ ਸਾਰੇ ਭੁਗਤਾਨ ਢੰਗਾਂ ਨੂੰ ਇੰਕ੍ਰਿਪਟ ਕਰਦਾ ਹੈਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਕਾਰਡਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋਕਾਰਡ ਸਿੰਕ ਕਰੋ
-
- ਕਰੈਡਿਟ ਕਾਰਡ ਜੋੜੋਕਾਰਡ ਜੋੜੋ
-
- ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋਕਾਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋਸਿਰਨਾਵਾਂ ਜੋੜੋਸਿਰਨਾਵਿਆਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ
-
- ਸਿਰਨਾਵੇਂ ਸੰਭਾਲੋ ਅਤੇ ਆਪਣੇ-ਆਪ ਭਰੋਸਿਰਨਾਵਿਆਂ ਨੂੰ ਸੰਭਾਲੋ ਅਤੇ ਭਰੋ
-
- ਨੰਬਰ, ਈਮੇਲ ਅਤੇ ਭੇਜਣ ਵਾਲੇ ਸਿਰਨਾਵਿਆਂ ਸਮੇਤ ਜਾਣਕਾਰੀਫ਼ੋਨ ਨੰਬਰਾਂ ਅਤੇ ਈਮੇਲ ਸਿਰਨਾਵਿਆਂ ਸਮੇਤ
@@ -1972,8 +1957,6 @@
ਕਾਰਡ ਨੂੰ ਹਟਾਓ
- ਕੀ ਤੁਸੀਂ ਇਹ ਕਰੈਡਿਟ ਕਾਰਡ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?
-
ਕਾਰਡ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?ਹਟਾਓ
@@ -1987,24 +1970,15 @@
ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡ
-
- ਵਾਜਬ ਕਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ ਦਿਓ ਜੀ
-
ਵਾਜਬ ਕਾਰਡ ਨੰਬਰ ਭਰੋ
-
- ਇਹ ਖੇਤਰ ਭਰੋਨਾਂ ਜੋੜੋਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡ ਵੇਖਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ
- ਆਪਣੇ ਕਰੈਡਿਟ ਕਾਰਡ ਸੁਰੱਖਿਅਤ ਕਰੋ
-
ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਭੁਗਤਾਨ ਢੰਗਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ
- ਆਪਣੀ ਡਿਵਾਇਸ ਲਈ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ, ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ ਤਾਂ ਜੋ ਕਿਸੇ ਹੋਰ ਹੱਥ ਤੁਹਾਡਾ ਡਿਵਾਇਸ ਹੋਣ ਉੱਤੇ ਤੁਹਾਡੇ ਸੰਭਾਲੇ ਪਾਸਵਰਡ ਸੁਰੱਖਿਅਤ ਰਹਿਣ।
-
ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ ਢੰਗਾਂ ਨੂੰ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਉੱਤੇ ਕਿਸੇ ਹੋਰ ਵੱਲੋਂ ਪਹੁੰਚ ਕਰਨ ਤੋਂ ਬਚਾਉਣ ਤੋਂ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਡਿਵਾਈਸ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ।ਹੁਣੇ ਸੈਟ ਅੱਪ ਕਰੋ
@@ -2012,8 +1986,6 @@
ਬਾਦ \'ਚਆਪਣਾ ਡਿਵਾਇਸ ਅਣ-ਲਾਕ ਕਰੋ
-
- ਸੰਭਾਲੀ ਕਰੈਡਿਟ ਕਾਰਡ ਜਾਣਕਾਰੀ ਵਰਤਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋਸੰਭਾਲੇ ਹੋਏ ਭੁਗਤਾਨ ਢੰਗਾਂ ਨੂੰ ਵਰਤਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ
@@ -2023,12 +1995,6 @@
ਸਿਰਨਾਵੇਂ ਨੂੰ ਸੋਧੋਸਿਰਨਾਵਿਆਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ
-
- ਨਾਂ ਦਾ ਪਹਿਲਾਂ ਹਿੱਸਾ
-
- ਮੱਧ ਨਾਂ
-
- ਨਾਂ ਦਾ ਆਖਰੀ ਹਿੱਸਾਨਾਂ
@@ -2054,8 +2020,6 @@
ਸਿਰਨਾਵੇਂ ਨੂੰ ਹਟਾਓ
-
- ਕੀ ਤੁਸੀਂ ਇਹ ਸਿਰਨਾਵੇਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?ਇਹ ਸਿਰਨਾਵੇਂ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?
@@ -2154,8 +2118,6 @@
ਹਟਾਓਸੋਧੋ
-
- ਕੀ ਤੁਸੀਂ ਇਹ ਲਾਗਇਨ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?ਕੀ ਤੁਸੀਂ ਇਸ ਪਾਸਵਰਡ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?
@@ -2163,41 +2125,23 @@
ਰੱਦ ਕਰੋ
-
- ਲਾਗਇਨ ਚੋਣਾਂਪਾਸਵਰਡ ਚੋਣਾਂ
-
- ਲਾਗਇਨ ਦੇ ਵੈੱਬ ਐਡਰੈਸ ਲਈ ਸੋਧਣਯੋਗ ਲਿਖਤ ਖੇਤਰ ਹੈ।ਵੈੱਬਸਾਈਟ ਸਿਰਨਾਵਿਆਂ ਲਈ ਸੋਧ ਕਰਨ ਯੋਗ ਲਿਖਤ ਖੇਤਰ।
-
- ਲਾਗਇਨ ਦੇ ਵਰਤੋਂਕਾਰ-ਨਾਂ ਲਈ ਸੋਧਣਯੋਗ ਲਿਖਤ ਖੇਤਰ ਹੈ।ਵਰਤੋਂਕਾਰ-ਨਾਂ ਲਈ ਸੋਧ ਕਰਨ ਯੋਗ ਲਿਖਤ ਖੇਤਰ।
- ਲਾਗਇਨ ਦੇ ਪਾਸਵਰਡ ਲਈ ਸੋਧਣਯੋਗ ਲਿਖਤ ਖੇਤਰ ਹੈ।
-
ਪਾਸਵਰਡ ਲਈ ਸੋਧ ਕਰਨ ਯੋਗ ਲਿਖਤ ਖੇਤਰ।
-
- ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗਇਨ ਲਈ ਸੰਭਾਲੋ।ਤਬਦੀਲੀਆਂ ਨੂੰ ਸੰਭਾਲੋ।
-
- ਸੋਧੋਪਾਸਵਰਡ ਨੂੰ ਸੋਧੋ
-
- ਨਵਾਂ ਲਾਗਇਨ ਜੋੜੋਪਾਸਵਰਡ ਜੋੜੋ
-
- ਪਾਸਵਰਡ ਚਾਹੀਦਾ ਹੈਪਾਸਵਰਡ ਦਿਓ
- ਵਰਤੋਂਕਾਰ-ਨਾਂ ਚਾਹੀਦਾ ਹੈ
-
ਵਰਤੋਂਕਾਰ-ਨਾਂ ਦਿਓਹੋਸਟ-ਨਾਂ ਚਾਹੀਦਾ ਹੈ
@@ -2545,6 +2489,8 @@
ਹਾਲੇ ਨਹੀਂਅਸਲ ਵੇਖਾਓ
+
+ ਅਸਲ ਨਾ-ਅਨੁਵਾਦ ਕੀਤਾ ਸਫ਼ਾ ਲੋਡ ਕੀਤਾਮੁਕੰਮਲ
@@ -2602,6 +2548,9 @@
ਉਲੱਥਾ ਸ਼ੀਟ ਬੰਦ ਕਰੋ
+
+ ਕੁਝ ਸੈਟਿੰਗਾਂ ਆਰਜ਼ੀ ਤੌਰ ਉੱਤੇ ਮੌਜੂਦ ਨਹੀਂ ਹਨ।
+
ਉਲੱਥੇ
@@ -2624,6 +2573,9 @@
”ਹਮੇਸ਼ਾ ਟਰਾਂਸਲੇਟ ਕਰੋ“ ਅਤੇ "ਕਦੇ ਟਰਾਂਸਲੇਟ ਨਾ ਕਰੋ" ਪਸੰਦਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰਨ ਲਈ ਭਾਸ਼ਾ ਚੁਣੋ।
+
+ ਭਾਸ਼ਾਵਾਂ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਬਾਅਦ ਵਿੱਚ ਮੁੜ ਜਾਂਚੋ।
+
ਟਰਾਂਸਲੇਸ਼ਨ ਲਈ ਪੇਸ਼ਕਸ਼ ਕਰੋ (ਮੂਲ)
@@ -2646,6 +2598,8 @@
%1$s ਨੂੰ ਹਟਾਓ
+
+ ਸਾਈਟਾਂ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਬਾਅਦ ਵਿੱਚ ਮੁੜ ਜਾਂਚੋ।%1$s ਨੂੰ ਹਟਾਉਣਾ ਹੈ?
@@ -2725,13 +2679,18 @@
ਪਿੱਛੇ ਜਾਓ
+
+ ਡੀਬੱਗ ਦਰਾਜ ਨੂੰ ਖੋਲ੍ਹੋ
+
ਟੈਬ ਟੂਲਟੈਬ ਗਿਣਤੀ
- ਸਰਗਰਮ
+ ਸਰਗਰਮ
+
+ ਸਰਗਰਮਨਾ-ਸਰਗਰਮ
@@ -2742,6 +2701,16 @@
ਟੈਬ ਬਣਾਉਣ ਵਾਲਾ ਟੂਲbਣਾਉਣ ਲਈ ਟੈਬਾਂ ਦੀ ਗਿਣਤੀ
+
+ ਲਿਖਤ ਖੇਤਰ ਖਾਲੀ ਹੈ
+
+ ਸਿਰਫ਼ ਸਕਰਾਤਮਕ ਮੁੱਲ ਹੀ ਭਰੋ
+
+ ਸਿਫ਼ਰ ਤੋਂ ਵੱਡਾ ਨੰਬਰ ਭਰੋ
+
+ ਇੱਕ ਕਾਰਵਾਈ ਰਾਹੀਂ ਵੱਧ ਤੋਂ ਵੱਧ ਤਿਆਰ ਹੋਣ ਵਾਲੀਆਂ ਟੈਬਾਂ (%1$s) ਦੀ ਗਿਣਤੀ ਅੱਪੜ ਗਈ ਹੈਸਰਗਰਮ ਟੈਬਾਂ ਵਿੱਚ ਜੋੜੋ
@@ -2758,11 +2727,11 @@
ਪਰਦੇਦਾਰੀ ਸੂਚਨਾ
- ਭੇਜੋ
+ ਭੇਜੋ
- ਬੰਦ ਕਰੋ
+ ਬੰਦ ਕਰੋ
- ਤੁਹਾਡੀ ਫ਼ੀਡਬੈਕ ਲਈ ਤੁਹਾਡਾ ਧੰਨਵਾਦ ਹੈ!
+ ਤੁਹਾਡੀ ਫ਼ੀਡਬੈਕ ਲਈ ਤੁਹਾਡਾ ਧੰਨਵਾਦ ਹੈ!ਬਹੁਤ ਸੰਤੁਸ਼ਟ
@@ -2774,6 +2743,14 @@
ਬਹੁਤ ਅਸੰਤੁਸ਼ਟ
+
+
+ ਸਰਵੇਖਣ ਨੂੰ ਖੋਲ੍ਹੋ
+
+ ਸਰਵੇਖਣ ਨੂੰ ਬੰਦ ਕਰੋ
+
+ ਬੰਦ ਕਰੋ
+
ਲਾਗਇਨ
diff --git a/mobile/android/fenix/app/src/main/res/values-pl/strings.xml b/mobile/android/fenix/app/src/main/res/values-pl/strings.xml
index 0ba564a816..bbf9f2122d 100644
--- a/mobile/android/fenix/app/src/main/res/values-pl/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-pl/strings.xml
@@ -49,12 +49,20 @@
- Ostatnio zachowane
+ Ostatnio zachowane
- Wyświetl wszystkie dodane zakładki
+ Wyświetl wszystkie dodane zakładki
- Usuń
+ Usuń
+
+
+
+ Zakładki
+
+ Wyświetl wszystkie zakładki
+
+ Usuń%1$s jest tworzony przez Mozillę.
@@ -143,8 +151,10 @@
Nowa karta prywatna
-
- Skrót do haseł
+
+ Hasła
+
+ Skrót do haseł
@@ -213,6 +223,8 @@
Synchronizuj ponownieZnajdź na stronie
+
+ Znajdź na stronie…Przetłumacz stronę
@@ -248,9 +260,29 @@
Dostosuj stronę startową
- Zaloguj się
-
- Synchronizuj hasła, karty i nie tylko
+ Zaloguj się
+
+ Synchronizuj hasła, karty i nie tylko
+
+
+ Ponownie zaloguj się do synchronizacji
+
+ Wstrzymano synchronizację
+
+ Nowa karta prywatna
+
+ Hasła
+
+
+ Nowości w przeglądarce %1$s
+
+ Wersja na komputery
+
+ Narzędzia
+
+ Zachowaj
@@ -558,6 +590,8 @@
Połącz ponownie, aby wznowić synchronizacjęJęzyk
+
+ TłumaczenieUdostępniane dane
@@ -626,6 +660,20 @@
Niedozwolone
+
+
+ Wymagane
+
+ Opcjonalne
+
+ Odczytywanie i zmienianie danych na witrynach
+
+ Usuń witrynę
+
+ Zezwalaj na wszystkich witrynach
+
+ Jeśli ufasz temu rozszerzeniu, możesz udzielić mu pozwolenia na każdej witrynie.
+
Inna kolekcja dodatków
@@ -650,7 +698,9 @@
Wskocz z powrotem
- Ostatnio dodane zakładki
+ Ostatnio dodane zakładki
+
+ ZakładkiOstatnio odwiedzone
@@ -2317,10 +2367,14 @@
Język źródłowy:Język docelowy:
+
+ Wypróbuj inny język źródłowyNie terazWyświetl w oryginale
+
+ Wczytano oryginalną nieprzetłumaczoną stronęOK
@@ -2340,7 +2394,7 @@
Nie obsługujemy jeszcze tego języka (%1$s).
- Więcej informacji
+ Więcej informacji
@@ -2354,7 +2408,9 @@
- Opcje tłumaczenia
+ Opcje tłumaczenia
+
+ Opcje tłumaczeniaZawsze proponuj tłumaczenie
@@ -2372,6 +2428,9 @@
Informacje o tłumaczeniach w przeglądarce %1$s
+
+ Zamknij funkcję tłumaczenia
+
Tłumaczenia
@@ -2494,6 +2553,8 @@
Narzędzia do debugowaniaPrzejdź wstecz
+
+
Narzędzia kart
@@ -2516,4 +2577,40 @@
Dodaj do nieaktywnych kartDodaj do prywatnych kart
+
+
+
+
+ Kontynuuj
+
+ Wypełnij tę ankietę
+
+ Zasady ochrony prywatności
+
+ Wyślij
+
+ Zamknij
+
+ Dziękujemy za opinię!
+
+
+ Bardzo zadowolony
+
+ Zadowolony
+
+ Obojętny
+
+ Niezadowolony
+
+ Bardzo niezadowolony
+
+
+
+ Dane logowania
+
+ Obecna domena: %s
+
+ Dodaj fałszywe dane logowania do tej domeny
+
+ Usuń dane logowania z nazwą użytkownika „%s”
diff --git a/mobile/android/fenix/app/src/main/res/values-pt-rBR/strings.xml b/mobile/android/fenix/app/src/main/res/values-pt-rBR/strings.xml
index ec824d3eaa..c8b4cdf923 100644
--- a/mobile/android/fenix/app/src/main/res/values-pt-rBR/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-pt-rBR/strings.xml
@@ -201,6 +201,10 @@
ExtensõesExtensões
+
+ Gerenciar extensões
+
+ Descobrir mais extensõesInformações da conta
@@ -219,6 +223,8 @@
Abrir em aba normalAdicionar à tela do dispositivo
+
+ Adicionar à tela do dispositivo…Instalar
@@ -230,10 +236,14 @@
Traduzir página
+ Salvar em coleção…
+
Salvar em coleçãoCompartilhar
+
+ Compartilhar…Abrir no %1$s
@@ -287,6 +297,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Salvar
+
+ Adicionar aos favoritos
+
+ Editar favorito
+
+ Salvar como PDF…
+
+ Ativar modo de leitura
+
+ Desativar modo de leitura
+
+ Traduzir página…
+
+ Traduzido para %1$s
+
+ Imprimir…
+
Nenhuma extensão aqui
@@ -384,8 +412,6 @@
Aviso de privacidade do Firefox
-
- Saiba mais em nosso aviso de privacidadeAdoramos manter você seguroIdioma
- Tradução
+ Tradução
+
+ TraduçãoEscolha de dados
@@ -667,10 +695,6 @@
ObrigatórioOpcional
-
- Ler e alterar dados de sites
-
- Excluir sitePermitir em todos os sites
@@ -798,8 +822,6 @@
HistóricoFavoritos
-
- Contas de acessoSenhas
@@ -826,8 +848,6 @@
and the third is the device model. -->
%1$s no %2$s %3$s
-
- Cartões de créditoMétodos de pagamento
@@ -843,6 +863,14 @@
Aba de %s
+
+
+ Abas do %1$s fechadas: %2$d
+
+ Ver abas fechadas recentemente
+
Exceções
@@ -1772,13 +1800,9 @@
Você pode facilmente adicionar este site à tela inicial do dispositivo para ter acesso imediato e navegar mais rápido com uma experiência semelhante a um aplicativo.
-
- Contas e senhasSenhas
- Salvar contas e senhas
-
Salvar senhasPerguntar se deve salvar
@@ -1793,46 +1817,27 @@
Preencher nomes de usuário e senhas em outros aplicativos no dispositivo.
-
- Adicionar conta
-
Adicionar senha
-
- Sincronizar contasSincronizar senhas
-
- Sincronizar contas entre dispositivosSincronizar senhas entre dispositivos
-
- Contas salvasSenhas salvas
- As contas que você salvar ou sincronizar no %s aparecem aqui.
-
As senhas que você salva ou sincroniza no %s aparecem aqui. Todas as senhas que você salva são criptografadas.
-
- Saiba mais sobre sincronização.Saiba mais sobre sincronizaçãoExceções
-
- Contas e senhas que não são salvas são mostradas aqui.O %s não salva senhas dos sites desta lista.
-
- Contas e senhas desses sites não serão salvas.O %s não salva senhas desses sites.Excluir todas as exceções
-
- Pesquisar contasProcurar senhas
@@ -1861,18 +1866,12 @@
Exibir senhaOcultar senha
-
- Desbloqueie para ver suas contas salvasDesbloqueie para ver as senhas salvas
-
- Proteja suas contas e senhasProteja as senhas salvas
- Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a suas contas e senhas salvas, caso outras pessoas usem seu dispositivo.
-
Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a suas senhas salvas, caso outras pessoas usem seu dispositivo.Mais tarde
@@ -1889,8 +1888,6 @@
Nome (A-Z)Data de uso
-
- Menu de ordenação de contasMenu de ordenação de senhas
@@ -1900,41 +1897,27 @@
Preenchimento automáticoEndereços
-
- Cartões de créditoMétodos de pagamento
- Salvar e preencher cartões automaticamente
-
Salvar e preencher métodos de pagamento
-
- Os dados são criptografadosO %s criptografa todos os métodos de pagamento que você salvaSincronizar cartões entre dispositivosSincronizar cartões
-
- Adicionar cartão de créditoAdicionar cartão
-
- Gerenciar cartões salvosGerenciar cartõesAdicionar endereçoGerenciar endereços
-
- Salvar e preencher endereços automaticamenteSalvar e preencher endereços
-
- Incluir informações como números, email e endereços de entregaIncluir números de telefone e endereços de email
@@ -1958,8 +1941,6 @@
Excluir cartão
- Tem certeza que quer excluir este cartão de crédito?
-
Excluir cartão?Excluir
@@ -1973,24 +1954,15 @@
Cartões salvos
-
- Digite um número de cartão de crédito válido
-
Digite um número de cartão válido
-
- Preencha este campoAdicionar um nomeDesbloqueie para ver seus cartões salvos
- Proteja seus cartões de crédito
-
Proteja seus métodos de pagamento salvos
- Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a seus cartões de crédito salvos, caso outras pessoas usem seu dispositivo.
-
Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a seus métodos de pagamento salvos, caso outras pessoas usem seu dispositivo.Configurar agora
@@ -1999,9 +1971,6 @@
Desbloquear dispositivo
-
- Desbloqueie para usar informações armazenadas de cartões de crédito
-
Desbloqueie para usar formas de pagamento salvas
@@ -2011,12 +1980,6 @@
Gerenciar endereços
-
- Primeiro nome
-
- Nome do meio
-
- SobrenomeNome
@@ -2042,8 +2005,6 @@
Excluir endereço
-
- Tem certeza que quer excluir este endereço?Excluir este endereço?
@@ -2142,49 +2103,29 @@
ExcluirEditar
-
- Tem certeza que quer excluir esta conta?Tem certeza que quer excluir esta senha?ExcluirCancelar
-
- Opções da contaOpções de senhas
-
- O campo de texto editável do endereço web da conta.O campo de texto editável do endereço do site.
-
- O campo de texto editável do nome de usuário da conta.O campo de texto editável do nome de usuário.
- O campo de texto editável da senha da conta.
-
O campo de texto editável da senha.
-
- Salvar alterações na conta.Salvar alterações.
-
- EditarEditar senha
-
- Adicionar contaAdicionar senha
-
- Senha é obrigatóriaDigite uma senha
- Nome de usuário é obrigatório
-
Digite um nome de usuárioNome de servidor é obrigatório
@@ -2597,6 +2538,9 @@
Fechar painel de tradução
+
+ Algumas configurações estão temporariamente indisponíveis.
+
Tradução
@@ -2619,6 +2563,9 @@
Selecione um idioma para gerenciar as preferências de ”sempre traduzir“ e ”nunca traduzir“.
+
+ Não foi possível carregar idiomas. Tente novamente mais tarde.
+
Oferecer tradução (padrão)
@@ -2641,6 +2588,8 @@
Remover %1$s
+
+ Não foi possível carregar sites. Tente novamente mais tarde.Excluir %1$s?
@@ -2719,13 +2668,18 @@
Voltar à página anterior
+
+ Abrir painel de depuração
+
Ferramentas de abasNúmero de abas
- Ativas
+ Ativas
+
+ AtivoInativas
@@ -2736,6 +2690,16 @@
Ferramenta de criação de abasNúmero de abas a criar
+
+ O campo de texto está vazio
+
+ Insira apenas números inteiros positivos
+
+ Insira um número maior que zero
+
+ Excedido o número máximo de abas (%1$s) que podem ser geradas em uma operaçãoAdicionar às abas ativas
@@ -2752,11 +2716,11 @@
Aviso de privacidade
- Enviar
+ Enviar
- Fechar
+ Fechar
- Obrigado por sua opinião!
+ Obrigado por sua opinião!Muito satisfeito
@@ -2768,6 +2732,14 @@
Muito insatisfeito
+
+
+ Abrir pesquisa de opinião
+
+ Fechar pesquisa de opinião
+
+ Fechar
+
Contas de acesso
diff --git a/mobile/android/fenix/app/src/main/res/values-pt-rPT/strings.xml b/mobile/android/fenix/app/src/main/res/values-pt-rPT/strings.xml
index 35a61211fc..3a9bbb4c9a 100644
--- a/mobile/android/fenix/app/src/main/res/values-pt-rPT/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-pt-rPT/strings.xml
@@ -201,6 +201,10 @@
ExtrasExtensões
+
+ Gerir extensões
+
+ Descubra mais extensõesInformações da conta
@@ -219,6 +223,8 @@
Abrir num separador normalAdicionar ao ecrã Inicial
+
+ Adicionar ao ecrã inicial…Instalar
@@ -230,9 +236,13 @@
Traduzir página
+ Guardar na coleção…
+
Guardar na coleçãoPartilhar
+
+ Partilhar…Abrir no %1$s
@@ -285,6 +295,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Guardar
+
+ Adicionar página aos marcadores
+
+ Editar marcador
+
+ Guardar como PDF…
+
+ Ativar Vista de leitura
+
+ Desativar a Vista de leitura
+
+ Traduzir página…
+
+ Traduzido para %1$s
+
+ Imprimir…
+
Sem extensões aqui
@@ -382,8 +410,6 @@
Política de privacidade do Firefox
-
- Saiba mais nas nossas informações de privacidadeAdoramos mantê-lo(a) seguro(a)Idioma
- Tradução
+ Tradução
+
+ TraduçõesOpções de dados
@@ -665,10 +693,6 @@
NecessárioOpcional
-
- Ler e alterar dados de websites
-
- Eliminar sitePermitir para todos os sites
@@ -774,7 +798,7 @@
Experimente reiniciar as extensões
- Tente reiniciar as extensões
+ Experimentar reiniciar as extensõesContinuar com as extensões desativadas
@@ -794,8 +818,6 @@
HistóricoMarcadores
-
- CredenciaisPalavras-passe
@@ -822,8 +844,6 @@
and the third is the device model. -->
%1$s no %2$s %3$s
-
- Cartões de créditoMétodos de pagamento
@@ -839,6 +859,14 @@
Separador de %s
+
+
+ %1$s separadores fechados: %2$d
+
+ Ver separadores fechados recentemente
+
Exceções
@@ -1769,12 +1797,8 @@
Pode adicionar facilmente este site ao ecrã inicial do seu dispositivo para ter acesso instantâneo e navegar mais rápido, com uma experiência semelhante ao de uma aplicação.
-
- Credenciais e palavras-passePalavras-passe
-
- Guardar credenciais e palavras-passeGuardar palavras-passe
@@ -1791,47 +1815,28 @@
Preencher nomes de utilizador e palavras-passe noutras aplicações no seu dispositivo.
-
- Adicionar credenciais
-
Adicionar palavra-passe
-
- Sincronização de credenciaisSincronizar palavras-passe
-
- Sincronizar credenciais entre dispositivosSincronize palavras-passe entre dispositivos
-
- Credenciais guardadasPalavras-passe guardadas
- As credenciais que guardar ou sincronizar com o %s serão apresentadas aqui.
-
As palavras-passe que guardar ou sincronizar com o %s serão listadas aqui. Todas as palavras-passe que guarda são encriptadas.
-
- Saber mais sobre a sincronização.Saber mais sobre a sincronizaçãoExceções
-
- As credenciais e palavras-passe que não estão guardadas serão mostradas aqui.O %s não irá guardar palavras-passe para sites listados aqui.
-
- As credenciais e palavras-passe não serão guardadas para estes sites.O %s não irá guardar as palavras-passe para estes sites.Eliminar todas as exceções
-
- Pesquisar credenciaisProcurar palavras-passe
@@ -1861,17 +1866,11 @@
Mostrar palavra-passeOcultar palavra-passe
-
- Desbloqueie para ver as credenciais guardadasDesbloqueie para ver as palavras-passe guardadas
- Proteja as suas credenciais e palavras-passe
-
Proteja as suas palavras-passe guardadas
- Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que as suas credenciais e palavras-passe guardadas sejam acedidas por outra pessoa que tenha acesso ao seu dispositivo.
-
Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que as suas palavras-passe guardadas sejam acedidas por outra pessoa que tenha acesso ao seu dispositivo.Mais tarde
@@ -1888,8 +1887,6 @@
Nome (A-Z)Última utilização
-
- Menu de ordenação de credenciaisMenu de ordenação de palavras-passe
@@ -1899,29 +1896,19 @@
Preenchimento automáticoEndereços
-
- Cartões de créditoMétodos de pagamento
- Guardar e preencher automaticamente cartões
-
Guardar e preencher métodos de pagamento
-
- Os dados são encriptadosO %s encripta todos os métodos de pagamento que guardaSincronizar cartões entre dispositivosSincronizar cartões
-
- Adicionar cartão de créditoAdicionar cartão
-
- Gerir cartões guardadosGerir cartões
@@ -1929,12 +1916,8 @@
Gerir endereços
-
- Guardar e preencher automaticamente endereçosGuardar e preencher endereços
-
- Incluir informações como números, e-mail e endereços de entregaInclui números de telefone e endereços de e-mail
@@ -1958,8 +1941,6 @@
Eliminar cartão
- Tem a certeza de que quer apagar este cartão de crédito?
-
Eliminar cartão?Apagar
@@ -1973,23 +1954,15 @@
Cartões guardados
-
- Por favor, introduza um número de cartão de crédito válidoInsira um número de cartão válido
-
- Por favor preencha este campoAdicionar um nomeDesbloquear para ver os cartões guardados
- Proteja os seus cartões de crédito
-
Proteja os seus métodos de pagamento guardados
- Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que os seus cartões de crédito guardados sejam acedidos por outra pessoa que tenha acesso ao seu dispositivo.
-
Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que os seus métodos de pagamento guardados sejam acedidos por outra pessoa que tenha acesso ao seu dispositivo.Configurar agora
@@ -1997,8 +1970,6 @@
Mais tardeDesbloquear o seu dispositivo
-
- Desbloquear para utilizar as informações de cartão de crédito armazenadasDesbloquear para utilizar métodos de pagamento guardados
@@ -2008,12 +1979,6 @@
Editar endereçoGerir endereços
-
- Primeiro nome
-
- Nome do meio
-
- Último nomeNome
@@ -2039,8 +2004,6 @@
Apagar endereço
-
- Tem a certeza de que quer eliminar este endereço?Eliminar este endereço?
@@ -2140,49 +2103,29 @@
EliminarEditar
-
- Tem a certeza que deseja eliminar esta credencial?Tem a certeza que quer eliminar esta palavra-passe?EliminarCancelar
-
- Opções de credenciaisOpções de palavra-passe
-
- O campo de texto editável para o endereço de Internet da credencial.O campo de texto editável para o endereço do site.
-
- O campo de texto editável para o nome de utilizador da credencial.O campo de texto editável para o nome de utilizador.
- O campo de texto editável para a palavra-passe da credencial.
-
O campo de texto editável para a palavra-passe.
-
- Guardar alterações na credencial.Guardar alterações.
-
- EditarEditar palavra-passe
-
- Adicionar nova credencialAdicionar palavra-passe
-
- É necessária uma palavra-passeIntroduza uma palavra-passe
- É necessário um nome de utilizador
-
Introduza um nome de utilizadorÉ necessário um nome de servidor
@@ -2525,13 +2468,13 @@
Traduzir para
- Tente outro idioma fonte
+ Tentar outro idioma fonteAgora nãoMostrar original
- Carregada página original não traduzida
+ Carregada a página original não traduzidaFeito
@@ -2588,6 +2531,9 @@
Fechar folha de traduções
+
+ Algumas definições estão temporariamente indisponíveis.
+
Traduções
@@ -2610,6 +2556,9 @@
Selecione um idioma para gerir as preferências “traduzir sempre” e “nunca traduzir”.
+
+ Não foi possível carregar os idiomas. Por favor, volte mais tarde.
+
Oferecer para traduzir (predefinição)
@@ -2632,6 +2581,8 @@
Remover %1$s
+
+ Não foi possível carregar os sites. Por favor, volte mais tarde.Eliminar %1$s?
@@ -2709,13 +2660,18 @@
Navegar de volta
+
+ Abrir caixa de depuração
+
Ferramentas de separadoresContagem de separadores
- Ativo
+ Ativo
+
+ AtivoInativo
@@ -2726,6 +2682,16 @@
Ferramenta de criação de separadoresQuantidade de separadores a criar
+
+ O campo de texto está vazio
+
+ Introduza apenas inteiros positivos
+
+ Introduza um número maior que zero
+
+ Excedido o número máximo de (%1$s) separadores que podem ser gerados numa operaçãoAdicionar aos separadores ativos
@@ -2740,24 +2706,32 @@
Concluir este questionário
- Política de privacidade
+ Informação de privacidade
- Submeter
+ Submeter
- Fechar
+ Fechar
- Obrigado pela sua opinião!
+ Obrigado pela sua opinião!Muito satisfeito(a)
- Satisfeito
+ Satisfeito(a)
- Neutro
+ Neutro(a)
- Insatisfeito
+ Insatisfeito(a)Muito insatisfeito(a)
+
+
+ Abrir inquérito
+
+ Fechar inquérito
+
+ Fechar
+
Credenciais
diff --git a/mobile/android/fenix/app/src/main/res/values-rm/strings.xml b/mobile/android/fenix/app/src/main/res/values-rm/strings.xml
index 84687df723..da3bde562b 100644
--- a/mobile/android/fenix/app/src/main/res/values-rm/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-rm/strings.xml
@@ -386,6 +386,8 @@
Dapli che 100 milliuns persunas protegian lur sfera privata cun tscherner in navigatur dad ina organisaziun senza finamira da profit.
+ Ils fastizaders enconuschents? Bloccads automaticamain. Extensiuns? Emprova tuttas 700. PDFs? Noss lectur integrà als administrescha senza problems.
+
Noss navigatur dad in\'organisaziun senza finamira da profit, gida ad evitar che interpresas ta persequiteschian a la zuppada en il web.\n
\nLegia dapli dal tema en nossas infurmaziuns davart la protecziun da datas.Расширения
+
+ Управление расширениями
+
+ Откройте для себя больше расширенийВаш аккаунт
@@ -224,6 +228,8 @@
Открыть в обычной вкладкеНа домашний экран
+
+ Добавить на домашний экран…Установить
@@ -235,9 +241,13 @@
Перевести страницу
+ Сохранить в коллекцию…
+
В сборникПоделиться
+
+ Поделиться…Открыть в %1$s
@@ -292,6 +302,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Сохранить
+
+ Добавить страницу в закладки
+
+ Изменить закладку
+
+ Сохранить как PDF…
+
+ Включить Вид для чтения
+
+ Отключить Вид для чтения
+
+ Перевести страницу…
+
+ Переведено на %1$s
+
+ Печать…
+
Здесь нет расширений
@@ -389,8 +417,6 @@
Уведомление о конфиденциальности Firefox
-
- Узнайте больше в нашем уведомлении о конфиденциальностиНам нравится обеспечивать вашу безопасностьЯзык
- Перевод
+ Перевод
+
+ ПереводыВыбор данных
@@ -672,12 +700,8 @@
Обязательно
- Необязательно
-
- Чтение и изменение данных веб-сайтов
+ Необязательные
-
- Удалить веб-сайтРазрешить для всех сайтов
@@ -803,8 +827,6 @@
ИсториюЗакладки
-
- ПаролиПароли
@@ -831,8 +853,6 @@
and the third is the device model. -->
%1$s на %2$s %3$s
-
- Банковские картыСпособы оплаты
@@ -848,6 +868,14 @@
Вкладка с %s
+
+
+ Закрыто %1$s вкладок: %2$d
+
+ Просмотр недавно закрытых вкладок
+
Исключения
@@ -1795,13 +1823,9 @@
Вы можете легко добавить этот сайт на домашний экран вашего устройства, чтобы иметь к нему мгновенный доступ.
-
- ПаролиПароли
- Сохранение паролей
-
Сохранять паролиПредлагать сохранить
@@ -1816,47 +1840,28 @@
Заполнять имена пользователей и пароли в других приложениях на вашем устройстве.
-
- Добавить логин
-
Добавить пароль
-
- Синхронизация логиновСинхронизировать пароли
-
- Синхронизировать логины между устройствамиСинхронизировать пароли между устройствами
-
- Сохранённые паролиСохранённые пароли
- Пароли, которые вы сохраняете или синхронизируете в %s, появятся тут.
-
Пароли, которые вы сохраните или синхронизируете в %s, будут показаны здесь. Все сохраняемые вами пароли зашифрованы.
-
- Узнайте больше о синхронизации.Узнайте больше о синхронизацииИсключения
-
- Здесь будут показаны не сохраняемые логины и пароли.%s не будет сохранять пароли для перечисленных здесь сайтов.
-
- Логины и пароли для этих сайтов сохраняться не будут.%s не будет сохранять пароли для этих сайтов.Удалить все исключения
-
- Поиск логиновПоиск паролей
@@ -1885,17 +1890,11 @@
Показать парольСкрыть пароль
-
- Разблокируйте, чтобы просмотреть сохранённые паролиРазблокируйте, чтобы просмотреть сохранённые пароли
- Защитите свои логины и пароли
-
Защитите сохранённые пароли
- Настройте графический ключ, Пин-код или пароль для блокировки устройства, чтобы защитить сохранённые пароли, если кто-либо ещё получит доступ к вашему устройству.
-
Настройте графический ключ, пин-код или пароль для разблокировки устройства, чтобы защитить сохранённые пароли на случай, если кто-либо ещё получит доступ к вашему устройству.Позже
@@ -1912,8 +1911,6 @@
По имени (А-Я)По последнему использованию
-
- Меню сортировки логиновМеню сортировки паролей
@@ -1923,41 +1920,27 @@
АвтозаполнениеАдреса
-
- Банковские картыСпособы оплаты
- Сохранять и автоматически заполнять данные карт
-
Сохранить и заполнять способы оплаты
-
- Данные зашифрованы%s шифрует все сохраняемые вами способы оплатыСинхронизировать карты между различными устройствамиСинхронизировать карты
-
- Добавить банковскую картуДобавить карту
-
- Управление сохранёнными картамиУправление картамиДобавить адресУправление адресами
-
- Сохранять и автоматически заполнять адресаСохранять и заполнять адреса
-
- Включая такие сведения, как номера, адреса эл. почты и доставокВключает номера телефонов и адреса электронной почты
@@ -1981,8 +1964,6 @@
Удалить карту
- Вы уверены, что хотите удалить эту банковскую карту?
-
Удалить карту?Удалить
@@ -1995,24 +1976,15 @@
Сохранённые карты
-
- Пожалуйста, введите правильный номер карты
-
Введите корректный номер карты
-
- Пожалуйста, заполните это полеДобавьте имяРазблокируйте, чтобы просмотреть сохранённые карты
- Защитите свои банковские карты
-
Защитите сохранённые способы оплаты
- Настройте графический ключ, Пин-код или пароль для блокировки устройства, чтобы защитить сохранённые банковские карты, если кто-либо ещё получит доступ к вашему устройству.
-
Настройте графический ключ, Пин-код или пароль для разблокировки устройства, чтобы защитить сохранённые способы оплаты, на случай, если кто-либо ещё получит доступ к вашему устройству.Настроить сейчас
@@ -2020,8 +1992,6 @@
ПозжеРазблокируйте своё устройство
-
- Разблокируйте, чтобы использовать сохранённые данные банковской картыРазблокируйте, чтобы использовать сохранённые способы оплаты
@@ -2031,12 +2001,6 @@
Изменить адресУправление адресами
-
- Имя
-
- Отчество
-
- ФамилияНазвание
@@ -2062,8 +2026,6 @@
Удалить адрес
- Вы уверены, что хотите удалить этот адрес?
-
Удалить этот адрес?Удалить
@@ -2161,49 +2123,29 @@
УдалитьПравить
-
- Вы уверены, что хотите удалить этот пароль?Вы уверены, что хотите удалить этот пароль?УдалитьОтмена
-
- Настройки логинаНастройки пароля
-
- Редактируемое текстовое поле для веб-адреса логина.Редактируемое текстовое поле для адреса веб-сайта.
-
- Редактируемое текстовое поле для имени пользователя логина.Редактируемое текстовое поле для имени пользователя.
- Редактируемое текстовое поле для пароля логина.
-
Редактируемое текстовое поле для пароля.
-
- Сохранить изменения в логине.Сохранить изменения.
-
- ПравкаИзменить пароль
-
- Добавить новый логинДобавить пароль
-
- Требуется парольВведите пароль
- Требуется имя пользователя
-
Введите имя пользователяВведите имя сервера
@@ -2611,6 +2553,9 @@
Закрыть область переводов
+
+ Некоторые настройки временно недоступны.
+
Переводы
@@ -2633,6 +2578,9 @@
Выберите язык для управления настройками «всегда переводить» и «никогда не переводить».
+
+ Не удалось загрузить языки. Пожалуйста, проверьте позже.
+
Предлагать перевод (по умолчанию)
@@ -2655,6 +2603,8 @@
Удалить %1$s
+
+ Не удалось загрузить сайты. Пожалуйста, проверьте позже.Удалить %1$s?
@@ -2732,13 +2682,18 @@
Перейти назад
+
+ Открыть панель отладки
+
Инструменты вкладокЧисло вкладок
- Активных
+ Активных
+
+ АктивныеНеактивных
@@ -2749,6 +2704,16 @@
Инструмент создания вкладокКоличество вкладок для создания
+
+ Текстовое поле пусто
+
+ Пожалуйста, введите только положительные целые числа
+
+ Пожалуйста, введите число больше нуля
+
+ Превышено максимальное число вкладок (%1$s), которое может быть сгенерировано за одну операциюДобавить в активные вкладки
@@ -2765,11 +2730,11 @@
Уведомление о конфиденциальности
- Отправить
+ Отправить
- Закрыть
+ Закрыть
- Спасибо за ваш отзыв!
+ Спасибо за ваш отзыв!Полностью удовлетворяет
@@ -2781,6 +2746,14 @@
Совсем не удовлетворяет
+
+
+ Открыть опрос
+
+ Закрыть опрос
+
+ Закрыть
+
Логины
diff --git a/mobile/android/fenix/app/src/main/res/values-sat/strings.xml b/mobile/android/fenix/app/src/main/res/values-sat/strings.xml
index 45ab837aed..4b085d93f8 100644
--- a/mobile/android/fenix/app/src/main/res/values-sat/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-sat/strings.xml
@@ -45,12 +45,21 @@
- ᱱᱤᱛ ᱥᱟᱺᱪᱟᱣᱟᱜ
+ ᱱᱤᱛ ᱥᱟᱺᱪᱟᱣᱟᱜ
- ᱡᱷᱚᱛᱚ ᱥᱟᱺᱪᱟᱣ ᱠᱟᱱ ᱵᱩᱠᱢᱟᱨᱠ ᱠᱚ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
+ ᱡᱷᱚᱛᱚ ᱥᱟᱺᱪᱟᱣ ᱠᱟᱱ ᱵᱩᱠᱢᱟᱨᱠ ᱠᱚ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
- ᱚᱪᱚᱜᱽ ᱢᱮ
+ ᱚᱪᱚᱜᱽ ᱢᱮ
+
+
+
+ ᱵᱩᱠᱢᱟᱨᱠ ᱠᱚ
+
+
+ ᱡᱷᱚᱛᱚ ᱵᱩᱠᱢᱟᱨᱠᱠᱚ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
+
+ ᱚᱪᱚᱜᱽ ᱢᱮ%1$s ᱛᱮᱭᱟᱨ ᱦᱩᱭ ᱠᱟᱱᱟ ᱢᱳᱡᱤᱞᱟ ᱫᱟᱨᱟᱭᱛᱮ ᱾
@@ -144,8 +153,10 @@
ᱱᱟᱶᱟ ᱱᱤᱡᱮᱨᱟᱜ ᱴᱮᱵᱽ
-
- ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫ ᱥᱚᱴᱠᱚᱴ
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫ ᱥᱚᱴᱠᱚᱴ
@@ -190,6 +201,10 @@
ᱮᱰ-ᱟᱸᱱᱥᱮᱠᱥᱴᱮᱱᱥᱚᱱᱠᱚ
+
+ ᱮᱠᱮᱴᱮᱱᱮᱚᱱ ᱠᱚ ᱢᱮᱱᱟᱡᱽ ᱢᱮ
+
+ ᱟᱨᱦᱚᱸ ᱰᱷᱮᱨ ᱮᱠᱥᱴᱮᱱᱥᱚᱱ ᱯᱟᱱᱛᱮ ᱢᱮᱠᱷᱟᱛᱟ ᱵᱤᱵᱨᱚᱬ
@@ -208,18 +223,26 @@
ᱱᱟᱶᱟ ᱴᱮᱵᱽ ᱨᱮ ᱡᱷᱤᱡᱽ ᱢᱮᱚᱲᱟᱜ ᱥᱠᱨᱤᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ
+
+ ᱚᱲᱟᱜ ᱥᱠᱨᱤᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱽ ᱢᱮ…ᱵᱚᱦᱟᱞ ᱢᱮᱨᱤᱥᱭᱝᱠᱥᱟᱦᱴᱟ ᱨᱮ ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ
+
+ ᱥᱟᱦᱴᱟ ᱨᱮ ᱯᱟᱱᱛᱮ ᱢᱮ…ᱥᱟᱦᱴᱟ ᱛᱚᱨᱡᱚᱢᱟᱭ ᱢᱮ
+ ᱛᱩᱢᱟᱹᱞ ᱨᱮ ᱥᱟᱺᱪᱟᱣ ᱢᱮ…
+
ᱛᱩᱢᱟᱹᱞ ᱨᱮ ᱥᱟᱺᱪᱟᱣ ᱢᱮᱦᱟᱹᱴᱤᱧ
+
+ ᱦᱟᱹᱴᱤᱧ ᱢᱮ…%1$s ᱨᱮ ᱡᱷᱤᱡᱽ ᱢᱮ
@@ -247,9 +270,46 @@
ᱚᱲᱟᱜᱥᱟᱦᱴᱟ ᱠᱩᱥᱤᱛᱮ ᱫᱚᱦᱚᱭ ᱢᱮ
- ᱵᱚᱞᱚᱱ ᱥᱩᱦᱤ
-
- ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ, ᱴᱮᱵᱽ ᱟᱨ ᱟᱨᱦᱚᱸ ᱟᱭᱢᱟ ᱡᱤᱱᱤᱥᱠᱚ ᱟᱹᱭᱩᱨ ᱢᱤᱫ ᱢᱮ
+ ᱵᱚᱞᱚᱱ ᱥᱩᱦᱤ
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ, ᱴᱮᱵᱽ ᱟᱨ ᱟᱨᱦᱚᱸ ᱟᱭᱢᱟ ᱡᱤᱱᱤᱥᱠᱚ ᱟᱹᱭᱩᱨ ᱢᱤᱫ ᱢᱮ
+
+
+ ᱥᱭᱝᱠ ᱞᱟᱹᱜᱤᱫ ᱵᱚᱞᱚᱱ ᱥᱩᱦᱤ ᱢᱮ
+
+ ᱟᱹᱭᱩᱨ ᱢᱤᱫ ᱛᱷᱩᱢ ᱠᱟᱱᱟ
+
+ ᱱᱟᱶᱟ ᱱᱤᱡᱮᱨᱟᱠ ᱴᱮᱵᱽ
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ
+
+ %1$s ᱨᱮ ᱱᱟᱶᱟ
+
+
+ ᱰᱮᱥᱠᱴᱚᱯ ᱥᱟᱭᱤᱴ ᱛᱮ ᱪᱟᱞᱟᱜ ᱢᱮ
+
+ ᱦᱟᱹᱛᱤᱭᱟᱹᱨ ᱠᱚ
+
+ ᱥᱟᱺᱪᱟᱣ ᱢᱮ
+
+ ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱵᱩᱩᱠᱢᱟᱨᱠ ᱢᱮ
+
+ ᱵᱩᱠᱢᱟᱨᱠ ᱥᱟᱯᱲᱟᱣ ᱢᱮ
+
+ PDF ᱞᱮᱠᱷᱟ ᱥᱟᱺᱪᱟᱣ ᱢᱮ…
+
+ ᱯᱟᱲᱦᱟᱣ ᱧᱮᱞᱡᱚᱝ ᱞᱮᱠᱷᱟ ᱮᱢ ᱪᱷᱚᱭ ᱢᱮ
+
+ ᱯᱟᱲᱦᱟᱣ ᱧᱮᱞᱡᱚᱝ ᱞᱮᱠᱷᱟ ᱵᱚᱸᱫᱚᱭ ᱢᱮ
+
+ ᱥᱟᱦᱴᱟ ᱛᱚᱨᱡᱚᱢᱟᱭ ᱢᱮ…
+
+ %1$s ᱛᱮ ᱛᱚᱨᱡᱚᱢᱟ ᱠᱟᱱᱟ
+
+ ᱪᱷᱟᱯᱟ…
@@ -347,8 +407,6 @@
ᱯᱷᱚᱭᱟᱨᱯᱷᱚᱠᱥ ᱡᱟᱹᱯᱛᱤ ᱠᱷᱚᱵᱚᱨ ᱾
-
- ᱟᱞᱮᱭᱟᱜ ᱱᱤᱥᱚᱱ ᱠᱷᱚᱵᱚᱨ ᱨᱮ ᱰᱷᱮᱨ ᱡᱤᱱᱤᱥ ᱥᱮᱬᱟᱭ ᱢᱮᱟᱢ ᱴᱷᱤᱠ ᱨᱮ ᱫᱚᱦᱚᱢᱮᱪᱷᱚ ᱞᱟᱹᱜᱤᱫ ᱠᱩᱥᱤᱭᱟᱜᱼᱟ ᱞᱮᱯᱟᱹᱨᱥᱤ
+
+ ᱛᱚᱨᱡᱚᱢᱟ
+
+ ᱛᱚᱨᱡᱚᱢᱟᱠᱚᱥᱟᱹᱠᱷᱤᱭᱟᱹᱛ ᱠᱩᱥᱤᱭᱟᱜ ᱠᱚ
@@ -623,6 +685,16 @@
ᱢᱟᱱᱟ ᱜᱮᱭᱟ
+
+
+ ᱞᱟᱹᱠᱛᱤ
+
+ ᱢᱚᱱᱮᱛᱮᱭᱟᱜ
+
+ ᱡᱷᱚᱛᱚ ᱥᱟᱭᱤᱴ ᱞᱟᱹᱜᱤᱫ ᱮᱢᱪᱷᱚᱭ ᱢᱮ
+
+ ᱟᱢ ᱡᱩᱫᱤ ᱱᱚᱶᱟ ᱮᱠᱥᱴᱮᱱᱥᱚᱱ ᱪᱮᱛᱟᱱ ᱨᱮ ᱵᱷᱚᱨᱥᱟ ᱮᱫ ᱠᱷᱟᱱ, ᱟᱢ ᱫᱚ ᱡᱷᱚᱛᱚ ᱣᱮᱵᱽᱥᱟᱭᱤᱴ ᱨᱮ ᱦᱚᱠᱮᱢ ᱮᱢ ᱫᱟᱲᱮ ᱟᱭᱟ ᱾
+
ᱠᱟᱹᱥᱴᱚᱢ ᱮᱰᱰᱼᱚᱱ ᱛᱩᱢᱟᱹᱞ
@@ -646,7 +718,9 @@
ᱦᱮᱡ ᱨᱩᱣᱟᱹᱲᱚᱜ ᱢᱮ
- ᱱᱤᱛᱚᱜᱼᱟᱜ ᱵᱩᱠᱢᱟᱨᱠ ᱠᱚ
+ ᱱᱤᱛᱚᱜᱼᱟᱜ ᱵᱩᱠᱢᱟᱨᱠ ᱠᱚ
+
+ ᱵᱩᱠᱢᱟᱨᱠᱠᱚᱱᱤᱛᱚᱜᱟᱜ ᱦᱤᱨᱤᱭᱟᱜ
@@ -741,8 +815,6 @@
ᱱᱟᱜᱟᱢᱵᱩᱠᱢᱟᱨᱠ ᱠᱚ
-
- ᱵᱚᱞᱚᱱ ᱠᱚᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ
@@ -768,8 +840,6 @@
and the third is the device model. -->
%1$s on %2$s %3$s
-
- ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰᱜᱚᱱᱚᱝ ᱦᱚᱨᱟᱠᱚ
@@ -786,6 +856,14 @@
%s ᱠᱷᱚᱱ ᱴᱮᱵᱽ
+
+
+ %1$s ᱴᱮᱵᱽᱠᱚ ᱵᱚᱸᱫ ᱠᱟᱱᱟ : %2$d
+
+ ᱱᱤᱛᱚᱜᱽᱼᱟᱜ ᱵᱚᱸᱫᱚᱼᱟᱜ ᱴᱮᱵᱽ ᱠᱚ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
+
ᱪᱷᱟᱰᱟ ᱠᱚ
@@ -1718,13 +1796,9 @@
ᱟᱢ ᱞᱚᱜᱚᱱ ᱵᱽᱨᱟᱣᱩᱡᱽ ᱟᱨ ᱮᱯ ᱞᱮᱠᱷᱟᱱ ᱢᱟᱨᱠᱷᱤ ᱤᱫᱤ ᱞᱟᱹᱜᱤᱫ ᱣᱮᱵᱥᱟᱭᱤᱴ ᱫᱚ ᱥᱟᱫᱷᱚᱱ ᱨᱮᱭᱟᱜ ᱚᱲᱟᱜ ᱥᱠᱨᱤᱱ ᱨᱮ ᱥᱮᱞᱮᱫᱽ ᱫᱟᱲᱮᱟᱜᱼᱟᱢ ᱾
-
- ᱵᱚᱞᱚᱱ ᱠᱚ ᱟᱨ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ
- ᱞᱚᱜᱤᱱ ᱠᱚ ᱟᱨ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱥᱟᱺᱪᱟᱣ ᱢᱮ
-
ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱥᱟᱺᱪᱟᱣ ᱢᱮᱥᱟᱺᱪᱟᱣ ᱞᱟᱹᱜᱤᱫᱛᱮ ᱠᱩᱠᱞᱤ
@@ -1740,46 +1814,27 @@
ᱟᱢᱟᱜ ᱥᱟᱫᱷᱚᱱ ᱨᱮ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱟᱨ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱯᱩᱨᱟᱹᱣ ᱢᱮ ᱾
-
- ᱵᱚᱞᱚ ᱥᱮᱞᱮᱫ ᱢᱮ
-
ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱥᱮᱞᱮᱫ ᱢᱮ
-
- ᱞᱚᱜᱤᱱ ᱠᱚ ᱥᱭᱝᱠ ᱢᱮᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽᱠᱚ ᱟᱹᱭᱩᱨ ᱢᱤᱫ ᱢᱮ
-
- ᱡᱷᱚᱛᱚ ᱥᱟᱫᱷᱚᱱ ᱵᱷᱤᱛᱨᱤ ᱨᱮ ᱵᱚᱞᱚ ᱠᱚ ᱥᱭᱝᱠ ᱢᱮᱡᱷᱚᱛᱚ ᱥᱟᱫᱷᱚᱱ ᱵᱷᱤᱛᱨᱤ ᱨᱮ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱟᱹᱭᱩᱨ ᱢᱤᱫ ᱢᱮ
-
- ᱥᱟᱺᱪᱟᱣᱟᱠᱟᱱ ᱞᱚᱜᱤᱱ ᱠᱚᱥᱟᱧᱪᱟᱣ ᱠᱟᱱ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱠᱚ
- ᱞᱚᱜᱤᱱ ᱚᱠᱟ %s ᱨᱮ ᱥᱟᱺᱪᱟᱣ ᱟᱨ ᱥᱭᱝᱠ ᱥᱟᱱᱟᱢ ᱠᱟᱱᱟ ᱚᱱᱟ ᱠᱚ ᱱᱚᱰᱮ ᱫᱮᱠᱷᱟᱣᱜᱼᱟ ᱾
-
ᱟᱢ %s ᱨᱮ ᱚᱞ ᱟᱠᱟᱱ ᱥᱮ ᱟᱹᱭᱩᱨ ᱢᱤᱫ ᱟᱠᱟᱱ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱱᱚᱸᱰᱮ ᱞᱤᱥᱴᱤ ᱟ ᱾ ᱟᱢ ᱡᱟᱦᱟᱸᱱ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱮᱢ ᱥᱟᱧᱪᱟᱣ ᱟ ᱚᱱᱟ ᱠᱚᱫᱚ ᱫᱟᱱᱟᱝᱟᱜᱼᱟ ᱾
-
- ᱥᱭᱝᱠ ᱵᱟᱵᱚᱛ ᱡᱟᱹᱥᱛᱤ ᱵᱟᱰᱟᱭ ᱢᱮ ᱾ᱥᱭᱝᱠ ᱵᱟᱵᱚᱛ ᱰᱷᱮᱨ ᱵᱟᱰᱟᱭ ᱢᱮᱪᱷᱟᱰᱟ ᱠᱚ
-
- ᱵᱚᱞᱚᱱ ᱥᱩᱦᱤ ᱟᱨ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱡᱟ ᱵᱟᱝ ᱥᱟᱺᱪᱟᱣ ᱠᱟᱱᱟ ᱚᱱᱟᱠᱩ ᱱᱚᱰᱮ ᱩᱫᱩᱜᱚᱣᱟ ᱾%s ᱫᱚ ᱱᱚᱰᱮ ᱞᱤᱥᱴᱤ ᱠᱟᱱ ᱥᱟᱭᱤᱴᱠᱚᱨᱮ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱵᱟᱭ ᱥᱟᱧᱪᱟᱣ ᱟ ᱾
-
- ᱞᱚᱜᱤᱱᱥ ᱟᱨ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱫᱚ ᱱᱚᱶᱟ ᱥᱟᱭᱤᱴ ᱞᱟᱹᱜᱤᱫ ᱵᱟᱝ ᱥᱟᱺᱪᱟᱣᱜᱼᱟ ᱾%s ᱫᱚ ᱱᱚᱰᱮ ᱢᱮᱱᱟᱜ ᱞᱤᱥᱴᱤ ᱠᱟᱱ ᱥᱟᱭᱤᱴᱠᱚᱨᱮ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱵᱟᱭ ᱥᱟᱧᱪᱟᱣ ᱟ ᱾ᱡᱷᱚᱛᱚ ᱪᱷᱟᱰᱟᱠᱚ ᱢᱮᱴᱟᱣ ᱢᱮ
-
- ᱞᱚᱜᱤᱱ ᱠᱚ ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
@@ -1808,17 +1863,11 @@
ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱫᱮᱠᱷᱟᱣᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱩᱠᱩ
-
- ᱥᱟᱺᱪᱟᱣᱠᱟᱱ ᱵᱚᱞᱚᱱ ᱥᱩᱦᱤ ᱠᱚ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱫ ᱛᱮ ᱚᱱᱞᱚᱠ ᱢᱮᱥᱟᱧᱪᱟᱣᱟᱠᱟᱱ ᱠᱟᱰ ᱠᱚ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱩᱞᱟᱹᱭ ᱢᱮ
- ᱟᱢᱟᱜ ᱞᱚᱜᱤᱱ ᱠᱚ ᱟᱨ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱡᱟᱯᱛᱤ ᱢᱮ
-
ᱟᱢᱟᱜ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱨᱩᱠᱷᱤᱭᱟᱹᱭ ᱢᱮ
- ᱥᱟᱫᱷᱚᱱ ᱠᱩᱞᱩᱯ ᱪᱤᱱᱦᱟᱹ, ᱯᱤᱱ, ᱟᱨ ᱵᱟᱝ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱞᱟᱜᱟᱣᱢᱮ ᱟᱢᱟᱜ ᱥᱟᱺᱪᱟᱣ ᱞᱚᱜᱤᱱ ᱠᱚ ᱮᱢᱟᱱ ᱨᱩᱠᱷᱭᱟ ᱞᱟᱹᱜᱤᱫ ᱡᱩᱫᱤ ᱚᱞᱜᱟ ᱦᱚᱲ ᱴᱷᱮᱱ ᱟᱢᱟᱜ ᱥᱟᱫᱷᱚᱱ ᱛᱟᱦᱮᱸᱱ ᱠᱷᱟᱱ ᱾
-
ᱥᱟᱫᱷᱚᱱ ᱠᱩᱞᱩᱯ ᱪᱤᱱᱦᱟᱹ, ᱯᱤᱱ, ᱟᱨ ᱵᱟᱝ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱟᱢᱟᱜ ᱥᱟᱧᱪᱟᱣ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱚ ᱮᱢᱟᱱ ᱨᱩᱠᱷᱭᱟ ᱞᱟᱹᱜᱤᱫ ᱡᱩᱫᱤ ᱚᱞᱜᱟ ᱦᱚᱲ ᱴᱷᱮᱱ ᱟᱢᱟᱜ ᱥᱟᱫᱷᱚᱱ ᱛᱟᱦᱮᱸᱱ ᱠᱷᱟᱱ ᱾ᱛᱟᱭᱚᱢ ᱛᱮ
@@ -1835,8 +1884,6 @@
ᱢᱟᱲᱟᱝ ᱵᱮᱵᱷᱟᱨᱟᱜ
-
- ᱞᱚᱜᱤᱱ ᱢᱮᱱᱭᱩ ᱥᱟᱞᱟᱭ ᱢᱮᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱢᱮᱱᱩ ᱥᱮᱴ ᱢᱮ
@@ -1846,17 +1893,11 @@
ᱟᱡ ᱛᱮ ᱯᱩᱨᱟᱹᱣᱴᱷᱤᱠᱬᱟᱤᱭᱟᱹ
-
- ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰᱜᱚᱱᱚᱝ ᱦᱚᱨᱟᱠᱚ
- ᱥᱟᱺᱪᱟᱣ ᱟᱨ ᱠᱟᱰ ᱠᱚ ᱟᱡ ᱛᱮ ᱯᱮᱨᱮᱡᱽ ᱢᱮ
-
ᱯᱮᱢᱮᱱᱴ ᱦᱚᱨᱟ ᱥᱟᱧᱪᱟᱣ ᱢᱮ ᱟᱨ ᱯᱮᱨᱮᱪ ᱢᱮ
-
- ᱰᱟᱴᱟ ᱫᱚ ᱮᱱᱠᱨᱤᱯᱴᱮᱰ ᱠᱟᱱᱟ%s ᱫᱚ ᱟᱢ ᱡᱟᱦᱟᱸ ᱥᱟᱧᱪᱟᱣ ᱮᱫ ᱡᱷᱚᱛᱚ ᱛᱚᱨᱠᱟᱠᱚ ᱨᱩᱠᱷᱤᱭᱟᱹ ᱟ
@@ -1864,25 +1905,16 @@
ᱠᱟᱰ ᱥᱭᱝᱠ ᱢᱮ
-
- ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱥᱮᱞᱮᱫᱽ ᱢᱮ
-
ᱠᱟᱰ ᱥᱮᱞᱮᱫᱽ ᱢᱮ
-
- ᱥᱟᱺᱪᱟᱣ ᱠᱟᱰ ᱠᱚ ᱢᱮᱱᱮᱡᱽ ᱢᱮᱠᱟᱰ ᱢᱮᱱᱮᱡᱽ ᱢᱮᱴᱷᱤᱠᱬᱟᱹ ᱥᱮᱞᱮᱫ ᱢᱮᱴᱷᱤᱠᱬᱟᱹᱤᱭᱟᱹ ᱡᱚᱛᱚᱱ ᱮᱢ
-
- ᱴᱷᱤᱬᱟᱹᱤᱭᱟᱹ ᱥᱟᱺᱪᱟᱣ ᱟᱨ ᱟᱡ ᱛᱮ ᱯᱮᱨᱮᱡ ᱢᱮᱴᱷᱤᱬᱟᱹᱤᱭᱟᱹ ᱥᱟᱧᱪᱟᱣ ᱟᱨ ᱟᱡ ᱛᱮ ᱯᱮᱨᱮᱡ ᱢᱮ
-
- ᱮᱞ, ᱤᱢᱮᱞ ᱟᱨ ᱵᱷᱮᱡᱟ ᱴᱷᱤᱠᱬᱟᱹ ᱞᱮᱠᱷᱟ ᱵᱤᱵᱨᱚᱬ ᱢᱮᱥᱟᱭ ᱢᱮᱯᱷᱚᱱ ᱱᱚᱢᱵᱚᱨ ᱟᱨ ᱤᱼᱢᱮᱞ ᱴᱷᱤᱠᱬᱟᱹ ᱥᱮᱞᱮᱫ ᱢᱮᱱᱟᱜᱼᱟ
@@ -1907,8 +1939,6 @@
ᱠᱟᱰ ᱢᱮᱴᱟᱣ ᱢᱮ
- ᱪᱮᱫ ᱟᱢ ᱜᱚᱴᱟ ᱛᱮ ᱢᱮᱱᱟᱢᱼᱟ ᱱᱚᱶᱟ ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱢᱮᱴᱟᱣ ᱞᱟ.ᱜᱤᱛ ᱛᱮ?
-
ᱠᱟᱰ ᱢᱮᱴᱟᱣᱟᱢ ᱥᱮ ?ᱢᱮᱴᱟᱣ ᱢᱮ
@@ -1920,44 +1950,34 @@
ᱵᱟᱹᱰᱨᱟᱹᱥᱟᱺᱪᱟᱣ ᱠᱟᱱ ᱠᱟᱰ
-
- ᱴᱷᱤᱠ ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱮᱞ ᱟᱫᱮᱨ ᱢᱮᱢᱤᱫᱴᱟᱝ ᱴᱷᱤᱠ ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱮᱞ ᱟᱫᱮᱨ ᱢᱮ
-
- ᱱᱚᱶᱟ ᱡᱟᱭᱜᱟ ᱯᱮᱨᱮᱡᱽ ᱢᱮᱧᱩᱛᱩᱢ ᱥᱮᱞᱮᱫ ᱢᱮᱥᱟᱺᱪᱟᱣᱟᱠᱟᱱ ᱠᱟᱰ ᱠᱚ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱩᱞᱟᱹᱭ ᱢᱮ
- ᱟᱢᱟᱜ ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱨᱩᱠᱷᱤᱭᱟᱹᱭ ᱢᱮ
-
ᱟᱢᱟᱜ ᱥᱟᱧᱪᱟᱣ ᱠᱟᱱ ᱜᱚᱱᱚᱝ ᱛᱚᱨᱠᱟᱠᱚ ᱨᱩᱠᱷᱤᱭᱟᱹᱭ ᱢᱮ
- ᱥᱟᱫᱷᱚᱱ ᱠᱩᱞᱩᱯ ᱪᱤᱱᱦᱟᱹ, ᱯᱤᱱ, ᱟᱨ ᱵᱟᱝ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱟᱢᱟᱜ ᱥᱟᱺᱪᱟᱣ ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱠᱚ ᱮᱢᱟᱱ ᱨᱩᱠᱷᱭᱟ ᱞᱟᱹᱜᱤᱫ ᱡᱩᱫᱤ ᱚᱞᱜᱟ ᱦᱚᱲ ᱴᱷᱮᱱ ᱟᱢᱟᱜ ᱥᱟᱫᱷᱚᱱ ᱛᱟᱦᱮᱸᱱ ᱠᱷᱟᱱ ᱾
+ ᱥᱟᱫᱷᱚᱱ ᱠᱩᱞᱩᱯ ᱪᱤᱱᱦᱟᱹ, ᱯᱤᱱ, ᱟᱨ ᱵᱟᱝ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫ ᱟᱢᱟᱜ ᱥᱟᱧᱪᱟᱣ ᱜᱚᱱᱚᱝ ᱛᱚᱨᱠᱟᱠᱚ ᱮᱢᱟᱱ ᱨᱩᱠᱷᱭᱟ ᱞᱟᱹᱜᱤᱫ ᱡᱩᱫᱤ ᱚᱞᱜᱟ ᱦᱚᱲ ᱴᱷᱮᱱ ᱟᱢᱟᱜ ᱥᱟᱫᱷᱚᱱ ᱛᱟᱦᱮᱸᱱ ᱠᱷᱟᱱ ᱾ᱱᱤᱛᱚᱜ ᱥᱟᱡᱟᱣ ᱢᱮᱛᱟᱭᱚᱢ ᱛᱮᱟᱢᱟᱜ ᱥᱟᱫᱷᱚᱱ ᱚᱱᱞᱚᱠ ᱢᱮ
-
- ᱫᱚᱦᱚ ᱠᱟᱱ ᱠᱨᱮᱰᱤᱴ ᱠᱟᱰ ᱵᱤᱵᱨᱚᱬ ᱠᱷᱩᱞᱟᱹᱭ ᱢᱮ
+
+ ᱥᱟᱧᱪᱟᱣ ᱠᱟᱱ ᱜᱚᱱᱚᱝ ᱛᱚᱨᱠᱟ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱠᱷᱤᱩᱞᱟᱹᱭ ᱢᱮᱴᱷᱤᱠᱬᱟᱹ ᱥᱮᱞᱮᱫ ᱢᱮᱴᱷᱤᱠᱬᱟᱹ ᱥᱟᱯᱲᱟᱣ ᱢᱮᱴᱷᱤᱠᱬᱟᱹᱤᱭᱟᱹ ᱡᱚᱛᱚᱱ ᱮᱢ
-
- ᱯᱩᱭᱞᱩ ᱧᱩᱛᱩᱢ
-
- ᱛᱟᱞᱟ ᱧᱩᱛᱩᱢ
-
- ᱢᱩᱪᱟᱹᱫ ᱧᱩᱛᱩᱢ
+
+ ᱧᱩᱛᱩᱢᱥᱚᱰᱚᱠ ᱴᱷᱤᱠᱬᱟᱹ
@@ -1982,7 +2002,7 @@
ᱴᱷᱤᱠᱬᱟᱹ ᱢᱮᱴᱟᱣ ᱢᱮ
- ᱪᱮᱫ ᱟᱢ ᱜᱚᱴᱟ ᱛᱮ ᱢᱮᱱᱟᱢᱼᱟ ᱱᱚᱶᱟ ᱴᱷᱤᱠᱬᱟᱹ ᱢᱮᱴᱟᱣ ᱞᱟ.ᱜᱤᱛ ᱛᱮ?
+ ᱱᱚᱶᱟ ᱴᱷᱤᱠᱬᱟᱹ ᱢᱮᱴᱟᱣᱟ ᱥᱮ ?ᱢᱮᱴᱟᱣ ᱢᱮ
@@ -2080,32 +2100,34 @@
ᱢᱮᱴᱟᱣ ᱢᱮᱥᱟᱯᱲᱟᱣ
-
- ᱪᱮᱫ ᱟᱢ ᱜᱚᱴᱟ ᱢᱮᱱᱟᱢᱼᱟ ᱱᱚᱶᱟ ᱞᱚᱜᱤᱱ ᱢᱮᱴᱟᱣ ᱞᱟ.ᱜᱤᱫ ᱛᱮ?
+
+ ᱪᱮᱫ ᱟᱢ ᱜᱚᱴᱟ ᱛᱮ ᱢᱮᱱᱟᱢᱼᱟ ᱱᱚᱶᱟ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱢᱮᱴᱟᱣ ᱞᱟ.ᱜᱤᱛ ᱛᱮ?ᱢᱮᱴᱟᱣ ᱢᱮᱵᱟᱹᱰᱨᱟᱹ
-
- ᱮᱴᱟᱜᱟᱜ ᱠᱚ ᱞᱚᱜᱤᱱ
-
- ᱣᱤᱵ ᱴᱷᱤᱠᱬᱟᱹ ᱞᱚᱜᱤᱱ ᱵᱚᱞᱚ ᱞᱟᱹᱜᱤᱫ ᱥᱟᱯᱲᱟᱣ ᱚᱞ ᱡᱟᱭᱜᱟ ᱾
-
- ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱞᱚᱜᱤᱱ ᱞᱟᱹᱜᱤᱫ ᱥᱟᱯᱲᱟᱣ ᱚᱞ ᱡᱟᱭᱜᱟ ᱾
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫ ᱨᱮᱭᱟᱜ ᱵᱟᱪᱷᱟᱣ ᱠᱚ
+
+ ᱣᱤᱵᱽ ᱴᱷᱤᱠᱬᱟᱹ ᱞᱟᱹᱜᱤᱫ ᱥᱟᱯᱲᱟᱣ ᱚᱞ ᱡᱟᱭᱜᱟ ᱾
+
+ ᱵᱤᱵᱷᱟᱨᱤᱭᱟᱹᱧᱩᱛᱩᱢ ᱞᱟᱹᱜᱤᱫ ᱥᱟᱯᱲᱟᱣ ᱚᱞ ᱡᱟᱭᱜᱟ ᱾
- ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱞᱚᱜᱤᱱ ᱞᱟᱹᱜᱤᱫ ᱥᱟᱯᱲᱟᱣ ᱚᱞ ᱡᱟᱭᱜᱟ ᱾
-
- ᱞᱚᱜᱤᱱ ᱵᱚᱫᱚᱞ ᱠᱚ ᱥᱟᱺᱪᱟᱣ ᱢᱮ ᱾
-
- ᱥᱟᱯᱲᱟᱣ
-
- ᱱᱟᱶᱟ ᱵᱚᱞᱚ ᱥᱮᱞᱮᱫ ᱢᱮ
-
- ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱨᱮᱭᱟᱜ ᱫᱚᱨᱠᱟᱨ ᱢᱮᱱᱟᱜ-ᱟ
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫ ᱞᱟᱹᱜᱤᱫ ᱥᱟᱯᱲᱟᱣ ᱚᱞ ᱡᱟᱭᱜᱟ ᱾
+
+ ᱵᱚᱫᱚᱞ ᱠᱚ ᱥᱟᱺᱪᱟᱣ ᱢᱮ ᱾
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱥᱟᱯᱲᱟᱣ ᱢᱮ
+
+ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱥᱮᱞᱮᱫ ᱢᱮ
+
+ ᱢᱤᱫᱴᱟᱹᱝ ᱥᱟᱵᱟᱫ ᱟᱫᱮᱨ ᱢᱮ
- ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱧᱩᱛᱩᱢ ᱫᱚᱨᱠᱟᱨ
+ ᱢᱤᱫᱴᱟᱹᱝ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱧᱩᱛᱩᱢ ᱟᱫᱮᱨ ᱢᱮᱦᱚᱥᱴᱧᱩᱛᱩᱢ ᱫᱚᱨᱠᱟᱨ ᱠᱟᱱᱟ
+
+ ᱢᱤᱫᱴᱟᱹᱝ ᱣᱮᱵᱽ ᱴᱷᱤᱠᱬᱟᱹ ᱟᱫᱮᱨ ᱢᱮᱨᱚᱲ ᱥᱮᱸᱫᱽᱨᱟ
@@ -2200,6 +2222,9 @@
%s ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ
+
+
+ ᱟᱢᱟᱜ ᱢᱩᱞ ᱵᱽᱨᱟᱣᱡᱚᱨ ᱛᱮ ᱩᱪᱟᱹᱲᱚᱜ ᱢᱮFirefox ᱟᱡ ᱛᱮ ᱠᱷᱩᱞᱟᱹ ᱪᱷᱚ ᱞᱟᱹᱜᱤᱫ ᱣᱮᱵᱥᱟᱭᱤᱴ, ᱤᱢᱮᱞ, ᱟᱨ ᱢᱮᱥᱮᱡᱽ ᱨᱮᱭᱟᱜ ᱞᱤᱝᱠ ᱥᱮᱴ ᱢᱮ ᱾
@@ -2237,6 +2262,85 @@
ᱥᱟᱡᱟᱣ ᱴᱷᱮᱱ ᱪᱟᱞᱟᱜ ᱢᱮ
+
+
+ ᱫᱩᱦᱲᱟᱹ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣᱤᱭᱟᱹ
+
+ ᱴᱷᱤᱠ ᱵᱟᱛᱟᱣᱟᱜᱠᱚ
+
+ ᱴᱷᱤᱠ ᱵᱟᱛᱟᱣᱟᱜ ᱟᱨ ᱵᱤᱱᱥᱨᱚᱛ ᱢᱮᱥᱟᱢᱤᱥᱤ ᱧᱮᱞᱵᱤᱲᱟᱹᱣᱟᱜᱠᱚ
+
+ ᱵᱤᱱᱥᱨᱚᱛ ᱧᱮᱞᱵᱤᱲᱟᱹᱣ
+
+ ᱱᱚᱶᱟ ᱧᱮᱞᱵᱤᱲᱟᱹᱣᱠᱚ ᱛᱤᱱᱟᱹᱜ ᱵᱷᱚᱨᱥᱟ ᱫᱮᱲᱮᱭᱟᱜᱼᱟᱢ ?
+
+ ᱨᱮᱴᱤᱝ ᱥᱚᱢᱚᱡᱚᱥ ᱮᱱᱟ
+
+ ᱵᱷᱚᱨᱥᱟᱡᱚᱱᱚᱠ ᱧᱮᱞᱵᱤᱲᱟᱹᱣ ᱪᱮᱛᱟᱱ ᱨᱮ
+
+ ᱱᱤᱛᱚᱜᱟᱜ ᱧᱮᱞᱵᱤᱲᱟᱹᱣ ᱠᱷᱚᱱ ᱛᱤᱱᱟᱹᱜ ᱜᱟᱱ ᱪᱤᱱᱦᱟᱹᱦᱟᱜ
+
+ ᱟᱞᱮ ᱫᱚ ᱧᱮᱞᱵᱤᱲᱟᱹᱣᱟᱜ ᱜᱩᱱ ᱫᱚ ᱪᱮᱫ ᱞᱮᱠᱷᱟ ᱞᱮ ᱵᱟᱲᱟᱭ ᱮᱫᱟ
+
+ Mozilla ᱯᱟᱦᱴᱟ ᱠᱷᱚᱱ %s ᱠᱷᱚᱱ AI ᱴᱮᱠᱱᱚᱞᱚᱡᱤ ᱵᱮᱵᱷᱟᱨ ᱠᱟᱛᱮᱜ ᱟᱞᱮ ᱯᱨᱚᱰᱚᱠᱴ ᱨᱤᱵᱷᱤᱭᱩ ᱨᱮᱱᱟᱜ ᱥᱟᱹᱨᱤᱜᱟᱱᱤ ᱧᱮᱞ ᱵᱤᱰᱟᱹᱣᱜ ᱮᱫᱟ ᱞᱮ ᱾ ᱱᱚᱶᱟ ᱫᱚ ᱧᱮᱞ ᱵᱤᱰᱟᱣᱜ ᱜᱩᱱ ᱵᱟᱲᱟᱭ ᱪᱷᱚ ᱨ ᱜᱚᱲᱚ ᱮᱢ ᱫᱟᱲᱮᱭᱟᱢᱟ, ᱯᱨᱚᱰᱚᱠᱴ ᱨᱮᱭᱟᱜ ᱢᱩᱞ ᱜᱩᱱ ᱵᱟᱵᱚᱛ ᱫᱚ ᱵᱟᱝᱟ ᱾
+
+ ᱪᱤᱠᱤ ᱜᱽᱨᱮᱰ A ᱠᱷᱚᱱ F ᱫᱷᱟᱹᱵᱤᱡ ᱞᱮ ᱮᱢ ᱮᱫᱟ ᱾]]>
+
+ %s ᱵᱟᱵᱚᱛ ᱰᱷᱮᱨ ᱵᱟᱰᱟᱭ ᱢᱮ ᱾
+
+ %s ᱫᱚ ᱧᱮᱞᱵᱤᱲᱟᱹᱣᱟᱜ ᱜᱩᱱ ᱫᱚ ᱪᱮᱫ ᱞᱮᱠᱷᱟ ᱵᱟᱲᱟᱭ ᱮᱫᱟ
+
+ ᱥᱟᱡᱟᱣᱠᱚ
+
+ ᱫᱩᱦᱲᱟᱹ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣᱤᱭᱟᱹ ᱨᱮ ᱫᱷᱟᱶᱨᱟ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
+
+ ᱰᱷᱮᱨ ᱥᱮᱬᱟᱭ ᱢᱮ
+
+ ᱫᱩᱦᱲᱟᱹ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣᱤᱭᱟᱹ ᱵᱚᱸᱫᱚᱭ ᱢᱮ
+
+ ᱰᱷᱮᱨ ᱮᱢ ᱧᱮᱞᱟ
+
+ ᱰᱷᱟᱶᱨᱟᱤᱭᱟᱹ ᱫᱚ %s
+
+ ᱫᱩᱦᱲᱟᱹ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣᱤᱭᱟᱹ ᱫᱚ %s ᱜᱚᱲᱚ ᱥᱟᱦᱚᱫ ᱮᱢ ᱠᱟᱜᱼᱟᱭ
+
+ %s Mozilla ᱛᱮ
+
+ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱫ ᱱᱚᱶᱟ ᱵᱤᱵᱨᱚᱬ
+
+ ᱱᱤᱛᱚᱜ ᱧᱮᱞ ᱢᱮ
+
+ ᱩᱱᱟᱹᱜ ᱧᱮᱞᱵᱤᱲᱟᱹᱣ ᱵᱟᱹᱱᱩᱜ ᱠᱟᱫᱟ
+
+ ᱛᱤᱧ ᱡᱷᱚᱜ ᱡᱤᱱᱤᱥ ᱨᱮ ᱡᱟᱹᱥᱛᱤ ᱧᱮᱞᱵᱤᱲᱟᱹᱣ ᱛᱟᱦᱮᱸᱱᱟ, ᱟᱞᱮ ᱫᱚ ᱚᱱᱟ ᱨᱮᱭᱟᱜ ᱜᱩᱱ ᱵᱚᱵᱚᱛ ᱞᱮ ᱢᱮᱱ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾
+
+ ᱡᱤᱱᱤᱥ ᱫᱚ ᱵᱟᱹᱱᱩᱜ ᱠᱟᱫᱟ
+
+ ᱡᱩᱫᱤ ᱥᱴᱚᱠ ᱛᱮ ᱡᱤᱱᱤᱥ ᱦᱮᱡ ᱞᱮᱠᱷᱟᱢ ᱵᱩᱡᱷᱟᱹᱣ ᱠᱮᱫ ᱠᱷᱟᱱ, ᱟᱞᱮ ᱴᱷᱮᱱ ᱠᱷᱚᱵᱚᱨ ᱮᱢ ᱠᱟᱜ ᱢᱮ ᱟᱞᱮ ᱫᱚ ᱧᱮᱞᱵᱤᱲᱟᱹᱣᱠᱚᱞᱮ ᱧᱮᱞ ᱟ ᱾
+
+ ᱠᱷᱚᱵᱚᱨ ᱢᱮ ᱡᱮ ᱡᱤᱱᱤᱥ ᱫᱚ ᱥᱴᱚᱠ ᱨᱮ ᱦᱮᱡ ᱦᱩᱭ ᱮᱱᱟ
+
+ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣ ᱜᱩᱱ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣ ᱮᱫᱟ (%s)
+
+ ᱱᱚᱶᱟ ᱫᱚ 60 ᱴᱤᱡ ᱜᱟᱱ ᱚᱠᱛᱚ ᱤᱫᱤᱭᱟᱭ ᱾
+
+ ᱠᱷᱚᱵᱚᱨ ᱮᱢ ᱞᱟᱹᱜᱤᱫ ᱟᱹᱰᱤ ᱥᱟᱯᱲᱟᱣ!
+
+ ᱟᱞᱮ ᱴᱷᱮᱱ ᱫᱚ ᱱᱚᱶᱟ ᱡᱤᱱᱤᱥ ᱵᱚᱵᱛ ᱧᱮᱞ ᱵᱤᱰᱟᱣᱜ 24 ᱴᱟᱲᱟᱝ ᱜᱟᱱ ᱞᱟᱣᱟ ᱞᱮᱭᱟ ᱾ ᱫᱟᱭᱟᱠᱟᱛᱮ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣ ᱢᱮ ᱾
+
+ ᱟᱞᱮ ᱫᱚ ᱱᱚᱶᱟ ᱵᱟᱞᱮ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ
+
+ ᱵᱤᱵᱨᱚᱬ ᱞᱚᱜᱚᱱ ᱜᱮ ᱦᱟᱹᱡᱩᱜ ᱠᱟᱱᱟ
+
+ ᱟᱞᱮ ᱴᱷᱮᱱ ᱫᱚ ᱱᱚᱶᱟ ᱡᱤᱱᱤᱥ ᱵᱚᱵᱛ ᱧᱮᱞ ᱵᱤᱰᱟᱣᱜ 24 ᱴᱟᱲᱟᱝ ᱜᱟᱱ ᱞᱟᱣᱟ ᱞᱮᱭᱟ ᱾ ᱫᱟᱭᱟᱠᱟᱛᱮ ᱧᱮᱞ ᱵᱤᱲᱟᱹᱣ ᱢᱮ ᱾
+
+ ᱯᱚᱨᱚᱠ ᱨᱮᱭᱟᱜ ᱦᱟᱹᱞᱤᱭᱟᱹᱠ ᱴᱷᱤᱠ ᱜᱭᱟ
+
+ ᱵᱩᱡᱷᱟᱹᱣ ᱠᱮᱫᱟ
+
+ ᱱᱤᱛᱚᱜ ᱪᱮᱫ ᱦᱚᱸ ᱵᱤᱵᱨᱚᱬ ᱵᱟᱹᱱᱩᱜ ᱠᱟᱫᱼᱟ
+
+ ᱱᱚᱶᱟ ᱮᱴᱠᱮᱴᱚᱬᱮ ᱥᱩᱫᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱠᱟᱹᱢᱤ ᱪᱟᱹᱞᱩ ᱠᱟᱱᱟ ᱾ ᱫᱟᱭᱟᱠᱟᱛᱮ ᱛᱟᱭᱚᱢ ᱛᱮ ᱫᱩᱦᱲᱟᱹ ᱧᱮᱞ ᱦᱟᱹᱡᱩᱜ ᱢᱮ ᱾ᱠᱚᱢ ᱫᱮᱠᱷᱟᱣ ᱢᱮ
@@ -2265,6 +2369,20 @@
+
+ ᱛᱚᱨᱡᱚᱢᱟ
+
+ ᱫᱩᱦᱲᱟᱹ ᱠᱩᱨᱩᱢᱩᱴᱩᱭ ᱢᱮ
+
+ ᱛᱚᱨᱡᱚᱢᱟᱜ ᱠᱟᱱᱟ
+
+ ᱛᱚᱨᱡᱚᱢᱟ ᱞᱟᱦᱟ ᱨᱮ ᱢᱮᱱᱟᱜ ᱠᱟᱫᱟ
+
+ ᱢᱤᱫᱴᱟᱝ ᱯᱟᱹᱨᱥᱤ ᱵᱟᱪᱷᱟᱣ ᱢᱮ
+
+ ᱛᱚᱨᱡᱚᱢᱟ ᱡᱷᱚᱜ ᱵᱷᱩᱞ ᱮᱴᱠᱮᱴᱚᱬᱮ ᱦᱩᱭᱮᱱᱟ ᱾ ᱫᱟᱭᱟᱠᱟᱛᱮ ᱫᱩᱦᱲᱟᱹ ᱪᱮᱥᱴᱟᱭ ᱢᱮ ᱾
+
+
ᱢᱳᱴ
@@ -2277,4 +2395,7 @@
ᱵᱟᱝ ᱠᱟᱹᱢᱤ ᱴᱮᱵᱽᱠᱚᱨᱮ ᱥᱮᱞᱮᱫ ᱢᱮᱱᱤᱡᱮᱨᱟᱜ ᱴᱮᱵᱽ ᱥᱮᱞᱮᱫᱽ ᱢᱮ
-
+
+
+
+
diff --git a/mobile/android/fenix/app/src/main/res/values-sc/strings.xml b/mobile/android/fenix/app/src/main/res/values-sc/strings.xml
index 799f6bb624..b126355172 100644
--- a/mobile/android/fenix/app/src/main/res/values-sc/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-sc/strings.xml
@@ -36,6 +36,8 @@
NòmineSeletziona una colletzione
+
+ Essi de sa modalidade de seletzione mùltipleSarva is ischedas seletzionadas a sa colletzione
@@ -43,11 +45,19 @@
- Sarvadas de reghente
+ Sarvadas de reghente
- Ammustra totu is sinnalibros sarvados
+ Ammustra totu is sinnalibros sarvados
- Boga
+ Boga
+
+
+
+ Sinnalibros
+
+ Ammustra totu is sinnalibros
+
+ Boga%1$s est prodotu dae Mozilla.
@@ -101,6 +111,8 @@
Iscarta
+
+ Cunfigura sa serrada in automàticu de is ischedas abertas chi non siant istadas visualizadas in s\'ùrtima die, chida o mese.Ammustra is optziones
@@ -127,8 +139,10 @@
Ischeda privada noa
-
- Curtzadòrgiu pro is craes
+
+ Craes
+
+ Curtzadòrgiu pro is craes
@@ -168,11 +182,17 @@
Firma
- Cumplementos
+ Cumplementos
+
+ Estensiones
+
+ Gesti is estensiones
+
+ Iscoberi àteras estensionesInformatziones de su contu
- Nissunu cumplementu inoghe
+ Nissunu cumplementu inogheAgiudu
@@ -187,18 +207,26 @@
Aberi in un’ischeda normaleAgiunghe a s’ischermu printzipale
+
+ Agiunghe a s’ischermu printzipale…
- Installa
+ InstallaTorra a sincronizareChirca in sa pàgina
+
+ Chirca in sa pàgina…Tradue sa pàgina
+ Sarva in una colletzione…
+
Sarva in una colletzioneCumpartzi
+
+ Cumpartzi…Aberi in %1$s
@@ -224,6 +252,50 @@
Personaliza sa pàgina printzipale
+
+ Identìfica·ti
+
+ Sincroniza craes, ischedas e àteru
+
+ Torra·ti a identificare pro sincronizare
+
+ Sincronizatzione in pàusa
+
+ Ischeda privada noa
+
+ Craes
+
+ Nou in %1$s
+
+ Càmbia a situ de iscrivania
+
+ Istrumentos
+
+ Sarva
+
+ Agiunghe custa pàgina a is sinnalibros
+
+ Modìfica su sinnalibru
+
+ Sarva comente PDF…
+
+ Ativa sa visualizatzione de letura
+
+ Disativa sa visualizatzione de letura
+
+ Tradue sa pàgina…
+
+ Traduidu in %1$s
+
+ Imprenta…
+
+
+
+ Nissuna estensione inoghe
+
Ischermu printzipale
@@ -234,6 +306,11 @@
Tradue sa pàgina
+
+ Pàgina traduida in %2$s dae: %1$s
+
Lìngua seletzionada
@@ -297,7 +374,6 @@
Avisu de riservadesa de Firefox
-
Nos praghet a t’amparare
@@ -467,6 +543,10 @@
Torra a connètere pro sighire cun sa sincronizatzioneLìngua
+
+ Tradutzione
+
+ TradutzionesSèberu de is datos
@@ -493,6 +573,9 @@
Cumpletamentu de URL in automàticuCussìgios dae is ispònsors
+
+ Sustene %1$s cun propostas isponsorizadas in manera ocasionaleCussìgios dae %1$s
@@ -515,9 +598,13 @@
Serrende s’aplicatzione pro aplicare is modìficas…
- Cumplementos
+ Cumplementos
+
+ Estensiones
- Installa unu cumplementu dae un’archìviu
+ Installa unu cumplementu dae un’archìviu
+
+ Installa un\'estensione dae un’archìviuNotìficas
@@ -526,9 +613,17 @@
Non permìtidu
+
+
+ Rechestu
+
+ Optzionale
+
+ Permite pro totu is sitos
+
- Colletzione de cumplementos personalizada
+ Colletzione de cumplementos personalizadaAB
@@ -541,10 +636,14 @@
Torra a s’ischeda
- Sinnalibros reghentes
+ Sinnalibros reghentes
+
+ SinnalibrosBisitadas de reghente
+
+ Istòrias chi faghent pensareArtìculos seletzionados dae %s
@@ -571,6 +670,8 @@
Àteras informatziones%s clàssicu
+
+ Sèrie de artistaSa colletzione Boghes indipendentes. %s
@@ -586,19 +687,31 @@
- Cumplementos noos a disponimentu
+ Cumplementos noos a disponimentu
+
+ Estensiones noas a disponimentuControlla is prus de chentu estensiones noas chi ti permitint de personalizare Firefox.
- Esplora cumplementos
+ Esplora cumplementos
+
+
+ Esplora is estensiones
-
+
- Is cumplementos sunt istados disativados in manera temporànea
+ Is cumplementos sunt istados disativados in manera temporànea
+
+ Is estensiones sunt disativadas in manera temporànea
- Proa torrende a aviare is cumplementos
+ Proa torrende a aviare is cumplementos
+
+ Proa torrende a aviare is estensiones
- Sighi cun is cumplementos disativados
+ Sighi cun is cumplementos disativados
+
+
+ Sighi cun is estensiones disativadas
@@ -613,10 +726,8 @@
CronologiaSinnalibros
-
- Credentziales
- Craes
+ CraesIschedas abertas
@@ -641,10 +752,8 @@
The first parameter is the application name, the second is the device manufacturer name
and the third is the device model. -->
%1$s in %2$s %3$s
-
- Cartas de crèditu
- Mètodos de pagamentu
+ Mètodos de pagamentuIndiritzos
@@ -658,11 +767,21 @@
Ischeda dae %s
+
+
+ Ischedas de %1$s serradas: %2$d
+
+ Ammustra ischedas serradas de reghente
+
EtzetzionesAtiva pro totu is sitos
+
+ Is estensiones ti permitint de disativare s\'amparu contra a sa sighidura in tzertos sitos.Àteras informatziones
@@ -1444,13 +1563,9 @@
Nòmine de su curtzadòrgiu
- Credentziales e craes
-
- Craes
-
- Sarva credentziales e craes
+ Craes
- Sarva is craes
+ Sarva is craesPregunta·mi·ddu
@@ -1463,42 +1578,24 @@
Cumpletamentu automàticu in àteras aplicatzionesCumpleta nòmines de utente e craes in àteras aplicatziones de su dispositivu tuo.
-
- Agiunghe credentziale
- Agiunghe crae
+ Agiunghe crae
-
- Sincronizatzione de credentziales
- Sincroniza is craes
-
- Sincronizatzione de credentziales intre dispositivos
+ Sincroniza is craes
- Sincroniza is craes intre dispositivos
-
- Credentziales sarvadas
+ Sincroniza is craes intre dispositivos
- Craes sarvadas
-
- Is credentziales chi as a sarvare o sincronizare cun %s ant a èssere ammustradas inoghe.
-
- Leghe àteru subra de Sync.
+ Craes sarvadas
- Àteras informatziones in pitzus de sa sincronizatzione
+ Àteras informatziones in pitzus de sa sincronizatzioneEtzetziones
-
- Is credentziales e is craes non sarvadas ant a èssere ammustradas inoghe.
-
- No ant a èssere sarvadas is credentziales e is craes de custos sitos.Cantzella totu is etzetziones
-
- Chirca credentziales
- Chirca craes
+ Chirca craesSitu
@@ -1523,12 +1620,6 @@
Ammustra sa craeCua sa crae
-
- Isbloca pro bìdere is credentziales sarvadas tuas
-
- Ampara is credentziales e is craes tuas
-
- Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is credentziales e is craes tuas de s’atzessu de àtera gente chi tèngiat su dispositivu tuo.A pustis
@@ -1545,44 +1636,30 @@
Cumpletamentu automàticuIndiritzos
-
- Cartas de crèditu
- Mètodos de pagamentu
-
- Sarva e cumpleta in automàticu is cartas
+ Mètodos de pagamentu
- Sarva e cumpleta cun is mètodos de pagamentu
-
- Is datos sunt tzifrados
+ Sarva e cumpleta cun is mètodos de pagamentu
- %s tzifrat totu is mètodos de pagamentu chi sarves
+ %s tzifrat totu is mètodos de pagamentu chi sarvesSincronizatzione de cartas intre dispositivosSincronizatzione de cartas
-
- Agiunghe una carta de crèditu
- Agiunghe una carta
-
- Gesti is cartas
+ Agiunghe una carta
- Gesti is cartas
+ Gesti is cartasAgiunghe un’indiritzuGesti is indiritzos
-
- Sarva e cumpleta in automàticu is indiritzos
- Sarva e cumpleta cun is indiritzos
-
- Include datos comente nùmeros, indiritzos eletrònicos e indiritzos de ispeditzione
+ Sarva e cumpleta cun is indiritzos
- Includet nùmeros de telèfonu e indiritzos eletrònicos
+ Includet nùmeros de telèfonu e indiritzos eletrònicosAgiunghe una carta
@@ -1603,9 +1680,7 @@
Cantzella sa carta
- Seguru chi boles cantzellare custa carta de crèditu?
-
- Boles cantzellare sa carta?
+ Boles cantzellare sa carta?Cantzella
@@ -1616,46 +1691,30 @@
AnnullaCartas sarvadas
-
- Inserta unu nùmeru de carta vàlidu
- Inserta unu nùmeru de carta vàlidu
-
- Cumpila custu campu
+ Inserta unu nùmeru de carta vàlidu
- Agiunghe unu nòmine
+ Agiunghe unu nòmineIsbloca pro bìdere is cartas sarvadas tuas
- Ampara is cartas de crèditu tuas
-
- Ampara is mètodos de pagamentu sarvados
-
- Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is cartas de crèditu sarvadas tuas de s’atzessu de àtera gente chi tèngiat su dispositivu tuo.
+ Ampara is mètodos de pagamentu sarvados
- Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is mètodos de pagamentu sarvados de s’atzessu de àtera gente chi tèngiat su dispositivu tuo.
+ Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is mètodos de pagamentu sarvados de s’atzessu de àtera gente chi tèngiat su dispositivu tuo.Cunfigura immoeA pustisIsbloca su disposivitu tuo
-
- Isbloca pro impreare informatzione sarvada de una carta de crèditu
- Isbloca pro impreare is mètodos de pagamentu sarvados
+ Isbloca pro impreare is mètodos de pagamentu sarvadosAgiunghe un’indiritzuModìfica s’indiritzuGesti is indiritzos
-
- Nòmine
-
- Segundu nòmine
-
- SangunaduIndiritzu postale
@@ -1679,9 +1738,7 @@
Cantzella s’indiritzu
- Seguru chi boles cantzellare custu indiritzu?
-
- Boles cantzellare custu indiritzu?
+ Boles cantzellare custu indiritzu?Cantzella
@@ -1776,38 +1833,24 @@
CantzellaModìfica
-
- Seguru chi boles cantzellare custa credentziale?
- Seguru chi boles cantzellare custa crae?
+ Seguru chi boles cantzellare custa crae?CantzellaAnnulla
-
- Optziones de credentziales
- Optziones de is craes
-
- Sarva is modìficas a sa credentziale.
+ Optziones de is craes
- Sarva is modìficas.
-
- Modìfica
+ Sarva is modìficas.
- Modìfica sa crae
-
- Agiunghe una credentziale noa
+ Modìfica sa crae
- Agiunghe una crae
-
- Crae rechesta
+ Agiunghe una crae
- Inserta una crae
-
- Nòmine de utente rechestu
+ Inserta una crae
- Inserta unu nòmine de utente
+ Inserta unu nòmine de utenteInserta un’indiritzu web
@@ -1885,7 +1928,7 @@
Chirca cun %s
-
+
Aberi in Firefox in manera automàtica is ligòngios de sitos web, de posta eletrònica e de messàgios.
@@ -1895,7 +1938,7 @@
Incarca inoghe pro àteros detàllios
- Nàviga in artu
+ Nàviga in artuSerra
@@ -2080,12 +2123,12 @@
Custa lìngua no est ancora atzetada: %1$s.
- Àteras informatziones
+ Àteras informatziones
- Optziones de tradutzione
+ Optziones de tradutzioneCunfiguratzione de sa tradutzione
@@ -2169,4 +2212,6 @@
Annulla
+
+
diff --git a/mobile/android/fenix/app/src/main/res/values-si/strings.xml b/mobile/android/fenix/app/src/main/res/values-si/strings.xml
index a90119065d..1f5dd3908d 100644
--- a/mobile/android/fenix/app/src/main/res/values-si/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-si/strings.xml
@@ -46,11 +46,19 @@
- මෑතදී සුරැකි
+ මෑතදී සුරැකි
- සුරැකි සියළු පොත්යොමු පෙන්වන්න
+ සුරැකි සියළු පොත්යොමු පෙන්වන්න
- ඉවත් කරන්න
+ ඉවත් කරන්න
+
+
+
+ පොත්යොමු
+
+ සියලුම පොත්යොමු පෙන්වන්න
+
+ ඉවත් කරන්නමොසිල්ලා හරහා %1$s නිෂ්පාදනය කෙරේ.
@@ -245,14 +253,28 @@
පිවිසෙන්න
+
+ මුරපද, පටිති සහ තවත් දෑ සමමුහූර්ත කරන්න
+
+ සමමුහූර්තයට පිවිසෙන්න
+
+ සමමුහූර්ත විරාමයකි
+
+ නව පෞද්. පටිත්තමුරපද
+
+ වැඩතල අඩවියමෙවලම්සුරකින්න
+
+
+ මෙතැන දිගු නැත
+
මුල් තිරය
@@ -264,6 +286,11 @@
පිටුව පරිවර්තනය
+
+ %1$s වෙතින් %2$s වෙත පිටුව පරිවර්තනය වී ඇත.
+
තෝරාගත් භාෂාව
@@ -342,6 +369,8 @@
ෆයර්ෆොක්ස් රහස්යතා දැන්වීම
+
+ රහස්යතා දැන්වීම ගැන තව දැනගන්නඔබට ආරක්ෂාව සලසන්නෙමු
@@ -533,6 +562,8 @@
සමමුහූර්තය යළි ඇරඹීමට නැවත සබඳින්නභාෂාව
+
+ පරිවර්තනයදත්ත තේරීම්
@@ -584,8 +615,12 @@
එක්කහු
+
+ දිගුගොනුවකින් එක්කහුවක් ස්ථාපනය…
+
+ ගොනුවකින් දිගුවක් ස්ථාපනයදැනුම්දීම්
@@ -594,9 +629,22 @@
ඉඩ නොදේ
+
+
+ වුවමනාය
+
+ විකල්පයකි
+
+ අඩවියේ දත්ත කියවා වෙනස් කිරීම
+
+
+ අඩවිය මකන්න
+
අභිරුචි එක්කහු එකතුව
+
+ අභිරුචි දිගු එකතුවහරි
@@ -613,7 +661,9 @@
ආපසු පනින්න
- මෑත පොත්යොමු
+ මෑත පොත්යොමු
+
+ පොත්යොමුමෑතදී ගොඩවැදුණු
@@ -664,6 +714,8 @@
දැන් නව එක්කහු තිබේ
+
+ දැන් නව දිගු තිබේෆයර්ෆොක්ස් අභිරුචිකරණයට උපකාරී වන නව දිගු 100 කට වඩා බලන්න.
diff --git a/mobile/android/fenix/app/src/main/res/values-sk/strings.xml b/mobile/android/fenix/app/src/main/res/values-sk/strings.xml
index b5795659e3..75648fb199 100644
--- a/mobile/android/fenix/app/src/main/res/values-sk/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-sk/strings.xml
@@ -201,6 +201,10 @@
DoplnkyRozšírenia
+
+ Spravovať rozšírenia
+
+ Objavte ďalšie rozšíreniaInformácie o účte
@@ -219,6 +223,8 @@
Otvoriť na bežnej kartePridať na úvodnú obrazovku
+
+ Pridať na úvodnú obrazovku…Nainštalovať
@@ -230,9 +236,13 @@
Preložiť stránku
+ Uložiť do kolekcie…
+
Uložiť do kolekcieZdieľať
+
+ Zdieľať…Otvoriť v aplikácii %1$s
@@ -289,6 +299,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Uložiť
+
+ Pridať stránku medzi záložky
+
+ Upraviť záložku
+
+ Uložiť ako PDF…
+
+ Zapnúť zobrazenie Čítačka
+
+ Ukončiť zobrazenie Čítačka
+
+ Preložiť stránku…
+
+ Preložená do jazyka %1$s
+
+ Tlačiť…
+
Nie sú tu žiadne rozšírenia
@@ -388,8 +416,6 @@
Vyhlásenie o ochrane osobných údajov Firefoxu
-
- Ďalšie informácie nájdete v našom Vyhlásení o ochrane osobných údajovRadi vás držíme v bezpečíJazyk
- Preklady
+ Preklady
+
+ PrekladyOdosielanie údajov
@@ -674,10 +702,6 @@
VyžadovanéVoliteľné
-
- Čítanie a zmena údajov webových stránok
-
- Odstrániť webovú stránkuPovoliť pre všetky stránky
@@ -804,8 +828,6 @@
HistóriaZáložky
-
- Prihlasovacie údajeHeslá
@@ -832,8 +854,6 @@
and the third is the device model. -->
%1$s na %2$s %3$s
-
- Platobné kartySpôsoby platby
@@ -850,6 +870,14 @@
Karta z %s
+
+
+ Zatvorené karty %1$su: %2$d
+
+ Zobraziť nedávno zatvorené karty
+
Výnimky
@@ -1778,13 +1806,9 @@
Túto webovú stránku si môžete jednoducho pridať na svoju domovskú obrazovku a mať tak okamžitý prístup k prehliadaniu.
-
- Prihlasovacie údajeHeslá
- Ukladanie prihlasovacích údajov
-
Ukladanie hesielPred uložením sa opýtať
@@ -1799,46 +1823,27 @@
Vypĺňa používateľské mená a heslá v iných aplikáciách vo vašom zariadení.
-
- Pridať prihlasovacie údaje
-
Pridať heslo
-
- Synchronizácia prihlasovacích údajovSynchronizácia hesiel
-
- Synchronizovať prihlasovacie údaje medzi zariadeniamiSynchronizovať heslá naprieč zariadeniami
-
- Uložené prihlasovacie údajeUložené heslá
- Uložené alebo synchronizované údaje v aplikácii %s sa zobrazia tu.
-
Heslá, ktoré uložíte alebo synchronizujete do %su budú zobrazené tu. Všetky heslá sú šifrované.
-
- Ďalšie informácie o službe Sync.Ďalšie informácie o synchronizáciiVýnimky
-
- Tu sa zobrazia prihlasovacie údaje, ktoré sa nebudú ukladať.%s nebude ukladať heslá pre tu uvedené stránky.
-
- Pre nasledujúce stránky sa nebudú ukladať prihlasovacie údaje.%s nebude ukladať heslá pre tieto stránky.Odstrániť všetky výnimky
-
- HľadaťHľadať v heslách
@@ -1867,17 +1872,11 @@
Zobraziť hesloSkryť heslo
-
- Pre zobrazenie prihlasovacích údajov odomknite zariadenieAk chcete zobraziť uložené heslá, odomknite zariadenie
- Zabezpečte svoje prihlasovacie údaje
-
Zabezpečte svoje heslá
- Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené prihlasovacie údaje v prípade, že vaše zariadenie bude používať niekto iný.
-
Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené heslá v prípade, že vaše zariadenie bude používať niekto iný.Neskôr
@@ -1894,8 +1893,6 @@
názvu (A-Z)posledného použitia
-
- Zoradiť ponuku prihlasovacích údajovPonuka pre zoradenie hesiel
@@ -1905,41 +1902,27 @@
Automatické dopĺňanieAdresy
-
- Platobné kartySpôsoby platby
- Ukladať a automaticky dopĺňať údaje o platobných kartách
-
Ukladať a dopĺňať spôsoby platby
-
- Údaje sú šifrované%s zašifruje všetky spôsoby platby, ktoré uložíteSynchronizovať platobné karty naprieč zariadeniamiSynchronizovať platobné karty
-
- Pridať platobnú kartuPridať kartu
-
- Spravovať uložené kartySpravovať kartyPridať adresuSpravovať adresy
-
- Ukladať a automaticky dopĺňať adresyUkladať a dopĺňať adresy
-
- Zahŕňa informácie ako sú čísla, e‑mailové adresy a dodacie adresyZahŕňa telefónne čísla a e‑mailové adresy
@@ -1963,8 +1946,6 @@
Odstrániť kartu
- Naozaj chcete odstrániť túto kreditnú kartu?
-
Odstrániť kartu?Odstrániť
@@ -1977,24 +1958,15 @@
Uložené karty
-
- Prosím, zadajte platné číslo platobnej karty
-
Zadajte platné číslo karty
-
- Vyplňte toto poleZadajte menoOdomknutím zobrazíte svoje uložené kreditné karty
- Zabezpečte svoje kreditné karty
-
Zabezpečte svoje uložené spôsoby platby
- Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené kreditné karty v prípade, že vaše zariadenie bude používať niekto iný.
-
Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené spôsoby platby v prípade, že vaše zariadenie bude používať niekto iný.Nastaviť teraz
@@ -2002,8 +1974,6 @@
NeskôrOdomknite svoje zariadenie
-
- Odomknutím použijete uložené informácie o kreditnej karteAk chcete použiť uložené spôsoby platby, odomknite zariadenie
@@ -2013,12 +1983,6 @@
Úprava adresySpravovať adresy
-
- Krstné meno
-
- Stredné meno
-
- PriezviskoMeno
@@ -2044,8 +2008,6 @@
Odstrániť adresu
-
- Naozaj chcete odstrániť túto adresu?Chcete odstrániť túto adresu?
@@ -2144,49 +2106,29 @@
OdstrániťUpraviť
-
- Naozaj chcete odstrániť tieto prihlasovacie údaje?Naozaj chcete odstrániť toto heslo?OdstrániťZrušiť
-
- Možnosti prihláseniaMožnosti hesiel
-
- Upraviteľné textové pole pre webovú adresu.Upraviteľné textové pole pre webovú adresu.
-
- Upraviteľné textové pole pre používateľské meno.Upraviteľné textové pole pre používateľské meno.
- Upraviteľné textové pole pre heslo.
-
Upraviteľné textové pole pre heslo.
-
- Uložiť zmeny prihlasovacích údajov.Uložiť zmeny
-
- UpraviťUpraviť heslo
-
- Pridať nové prihlasovacie údajePridať heslo
-
- Vyžaduje sa hesloZadajte heslo
- Vyžaduje sa používateľské meno
-
Zadajte používateľské menoVyžaduje sa názov hostiteľa
@@ -2594,6 +2536,9 @@
Zavrieť hárok Preklady
+
+ Niektoré nastavenia sú dočasne nedostupné.
+
Preklady
@@ -2617,6 +2562,9 @@
Vyberte jazyk, pre ktorý chcete spravovať predvoľby „Vždy prekladať“ a „Nikdy neprekladať“.
+
+ Nepodarilo sa načítať jazyky. Skúste to neskôr.
+
Ponúkať preklad (predvolené)
@@ -2640,6 +2588,8 @@
Odstrániť %1$s
+
+ Stránky sa nepodarilo načítať. Skúste to neskôr.Odstrániť %1$s?
@@ -2717,13 +2667,18 @@
Prejsť dozadu
+
+ Otvoriť zásuvku na ladenie
+
Nástroje pre kartyPočet kariet
- Aktívne
+ Aktívne
+
+ AktívneNeaktívne
@@ -2734,6 +2689,16 @@
Nástroj na vytváranie karietPočet kariet, ktorý chcete vytvoriť
+
+ Textové pole je prázdne
+
+ Zadajte iba kladné celé čísla
+
+ Zadajte číslo väčšie ako nula
+
+ Prekročili ste maximálny počet kariet (%1$s), ktoré je možné vygenerovať v rámci jednej operáciePridať medzi aktívne karty
@@ -2750,11 +2715,11 @@
Vyhlásenie o ochrane osobných údajov
- Odoslať
+ Odoslať
- Zavrieť
+ Zavrieť
- Ďakujeme za vašu spätnú väzbu.
+ Ďakujeme za vašu spätnú väzbu.veľmi spokojný
@@ -2766,6 +2731,14 @@
veľmi nespokojný
+
+
+ Otvoriť prieskum
+
+ Zavrieť prieskum
+
+ Zavrieť
+
Prihlasovacie údaje
diff --git a/mobile/android/fenix/app/src/main/res/values-skr/strings.xml b/mobile/android/fenix/app/src/main/res/values-skr/strings.xml
index bec0a1a1c1..7461c7baa6 100644
--- a/mobile/android/fenix/app/src/main/res/values-skr/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-skr/strings.xml
@@ -55,6 +55,9 @@
ہٹاؤ
+
+
+ نشانیاںہٹاؤ
@@ -371,8 +374,6 @@
فائرفوکس رازداری نوٹس
-
- ساݙے رازداری نوٹس وچ ٻیا سکھواَساکوں تُہاکوں محفوظ رکّھݨ بھان٘دا ہِے
- ترجمہ
+ ترجمہڈیٹا چوائس
@@ -654,10 +655,6 @@
ضروری ہےآپشنل
-
- ویب سائٹ ڈیٹا پڑھو تے تبدیلی کرو
-
- ویب سائٹ مٹاؤساریاں سائٹاں کیتے اجازت ݙیوو
@@ -789,8 +786,6 @@
نشانیاں
-
- لاگ ان آںپاس ورڈز
@@ -815,8 +810,6 @@
The first parameter is the application name, the second is the device manufacturer name
and the third is the device model. -->
%3$s %2$s تے %1$s
-
- کریڈٹ کارڈزادائیگی طریقے
@@ -1772,13 +1765,9 @@
تساں ایں ویب سائٹ کوں آسانی نال آپݨی ڈیوائس دی ہوم سکرین وچ شامل کر سڳدے ہو تاں جو فوری رسائی حاصل تھیوے تے ایپ جیہے تجربے نال تیزی نال براؤز کرو۔
-
- لاگ ان تے پاس ورڈپاس ورڈز
- لاگ ان تے پاس ورڈ محفوظ کرو
-
پاس ورڈ محفوظ کرومحفوظ کرݨ کیتے پُچھو
@@ -1792,46 +1781,28 @@
ٻیاں ایپاں وچ آٹوفل کروآپݨی ڈیوائس تے موجود ٻیاں ایپاں وچ ورتݨ ناں تے پاس ورڈ بھرو۔
-
- لاگ ان شامل کروپاس ورڈ شامل کرو
-
- لاگ اناں کوں ہم وقت کروپاس ورڈ ہم وقت کرو
-
- ڈیوائساں دے مابین لاگ ان ہم وقت کروڈیوائساں دے وِچالے پاس ورڈز کوں ہم وقت کرو
-
- محفوظ تھئے لاگ انمحفوظ تھئے پاس ورڈ
- تساں جہڑے لاگ ان محفوظ کریندے ہو یا %s نال ہم وقت کریندے ہو او اِتھاں ݙکھائے ویسن۔
-
تُساں جہڑے پاس ورڈز محفوظ کرین٘دے ہِیوے یا %s نال ہم وقت کرین٘دے ہِیوے اُوہ اِتّھاں درج ہوسِن۔ تُہاݙے محفوظ کِیتا ڳئے سبّھے پاس ورڈز کوں انکرپٹ کِیتا ڳِیا ہِے۔
-
- ہم وقت کرݨ بارے ٻیا سِکھو۔ہم وقت کرݨ بارے ٻیا سِکھو۔استثنیات
-
- جہڑے لاگ ان تے پاس ورڈ محفوظ کائنی کیتے ڳئے او اِتھ ݙکھائے ویسن۔%s اِتّھاں درج سائٹاں دے پاس ورڈز محفوظ نہ کریسی۔
-
- انہاں سائٹاں کیتے لاگ تے پاس ورڈ محفوظ کائناں تھیسن۔%s اِنّھاں سائٹاں دے پاس ورڈز محفوظ نہ کریسی۔سارے استثناء مٹاؤ
-
- لاگ ان ڳولوپاس ورڈز ڳولو
@@ -1862,17 +1833,11 @@
پاس ورڈ لکاؤ
-
- آپݨے محفوظ کیتے لاگ اناں کوں ݙیکھݨ کیتے اݨ لاک کروآپݨے محفوظ تھئے پاس ورڈاں کوں ݙیکھݨ کیتے اݨ لاک کرو
- لاگ ان تے پاس ورڈ دی محفوظ بݨاؤ
-
آپݨے محفوظ تھئے ہوئے پاس ورڈز کوں محفوظ بݨاؤ
- جے تہاݙے کول کوئی ٻئی ڈیوائس ہے تاں آپݨے محفوظ کیتے لاگ ان تے پاس ورڈ تائیں پہنچ کنوں بچݨ سانگے ڈیوائس لاگ ان پیٹرن، پن پاس ورڈ قائم کرو۔
-
ڄیکر تُہاݙی ڈیوائس کہیں ٻئے کول ہِے تاں آپݨے محفوظ کِیتے ڳئے پاس ورڈز تئیں پہنچ کنوں بچاوݨ کِیتے ڈیوائس لاک پیٹرن، PIN، یا پاس ورڈ مُرتّب کرو۔بعد وچ
@@ -1889,8 +1854,6 @@
ناں(A-Z)چھیکڑی ورتاوا
-
- لاگ ان مینیو کوں ترتیب ݙیووپاس ورڈز مینیو کوں مُرتّب کرو
@@ -1900,40 +1863,26 @@
خودبخود بھرݨپتے
-
- کریڈٹ کارڈزادائیگی طریقے
- کارڈ محفوظ کرو تے آپݨے آپ بھرو
-
ادائیگی دے طریقے محفوظ اَتے پُر کرو
-
- ڈیٹا مخفی ہے۔%sتُہاݙے محفوظ کِیتے ڳئے ادائیگی دے سبّھے طریقیاں کوں انکرپٹ کرین٘دا ہِےڈیوائساں دے مابین کارڈ ہم وقت کروکارڈ ہم وقت کرو
-
- کریڈٹ کارڈ شامل کروکارڈ شامل کرو
-
- محفوظ تھئے کارڈ منیج کروکارڈز منیج کروپتہ شامل کروپتے منیج کرو
-
- محفوظ کرو تے پتے خودبخود بھرومحفوظ کرو تے پتے پُر کرو
-
- معلومات شامل کرو، مثلاً تعداد، ای میل تے شپنگ پتےفون لمبرز اَتے ای میل پتے شامل ہِن
@@ -1957,8 +1906,6 @@
کارڈ مٹاؤ
- بھلا تہاکوں پک ہے جو تساں ایہ کریڈٹ کارڈ مٹاوݨ چاہندے ہو؟
-
کارڈ مٹاؤں؟مٹاؤ
@@ -1970,23 +1917,15 @@
منسوخ کرومحفوظ تھئے کارڈ
-
- سوہݨا، ٹھیک کریڈٹ کارڈ نمبر درج کروہک درست کارڈ نمبر درج کرو۔
-
- سوہݨا، ایہ خانہ پُر کروناں شامل کروآپݨے محفوظ تھئے کارڈاں کوں ݙیکھݨ کیتے اݨ لاک کرو
- آپݨے کریڈٹ کارڈاں کوں محفوظ بݨاؤ
-
آپݨے محفوظ کِیتے ڳئے ادائیگی دے طریقیاں کوں محفوظ بݨاؤ
- جے تہاݙے کول کوئی ٻئی ڈیوائس ہے تاں آپݨے محفوظ کیتے کریڈٹ کارڈ تائیں پہنچ کنوں بچݨ سانگے ڈیوائس لاگ ان پیٹرن، پن پاس ورڈ قائم کرو۔
-
ڄیکر تُہاݙی ڈیوائس کہیں ٻئے کول ہِے تاں آپݨے محفوظ کِیتے ڳئے ادائیگی دے طریقیاں تئیں پہنچ کنوں بچاوݨ کِیتے ڈیوائس لاک پیٹرن، PIN، یا پاس ورڈ مُرتّب کرو۔بݨ قائم کرو
@@ -1994,8 +1933,6 @@
بعد وچآپݨی ڈیوائس اݨ لاک کرو
-
- ذخیرہ تھئی کریڈٹ کارڈ ڄاݨکاری کوں ورتݨ کیتے اݨ لاک کرومحفوظ کِیتے ڳئے ادائیگی دے طریقے استعمال کرݨ کِیتے غیر مقفّل کرو
@@ -2004,12 +1941,6 @@
پتے وچ تبدیلی کروپتے منیج کرو
-
- پہلا ناں
-
- وچلا ناں
-
- چھیکڑی ناںناں
@@ -2037,8 +1968,6 @@
پتہ مٹاؤ
-
- بھلا تہاکوں پک ہے جو تساں ایہ پتہ مٹاوݨ چاہندے ہو؟ایہ پتہ مٹاؤں؟
@@ -2141,49 +2070,29 @@
مٹاؤتبدیلی کرو
-
- بھلا تہاکوں پک ہے جو تساں ایہ لاگ ان مٹاوݨ چاہندے ہو؟بَھلا تُہاکُوں پَک ہِے جو تُساں اِیں پاس ورڈ کوں مٹاوݨ چاہن٘دے ہِیوے؟مٹاؤمنسوخ کرو
-
- لاگ ان آپشناںپاس ورڈ آپشناں
-
- لاگ ان دے ویب پتے کیتے عبارت تبدیل کرݨ دے قابل خانہ۔ویب سائٹ ایڈریس کِیتے قابلِ تدوین ٹیکسٹ فیلڈ۔
-
- لاگ ان دے ورتݨ ناں کیتے عبارت تبدیل کرݨ دے قابل خانہ۔صارف ناں کیتے عبارت تبدیل کرݨ دے قابل خانہ۔
- لاگ ان دے پاس ورڈ کیتے عبارت تبدیل کرݨ دے قابل خانہ۔
-
پاس ورڈ کیتے عبارت تبدیل کرݨ دے قابل خانہ۔
-
- لاگ ان وچ تبدیلیاں محفوظ کرو۔تبدیلیاں محفوظ کرو۔
-
- تبدیلی کروپاس ورڈ وچ تبدیلی کرو
-
- نواں لاگ ان شامل کروپاس ورڈ شامل کرو
-
- پاس ورڈ ضروری ہےپاس ورڈ درج کرو
- ورتݨ ناں ضروری ہے
-
ورتݨ ناں درج کروہوسٹ ناں ضروری ہے
@@ -2718,7 +2627,7 @@
ٹیب شمار
- فعال
+ فعالغیر فعال
@@ -2745,11 +2654,11 @@
رازداری نوٹس
- جمع کرواؤ
+ جمع کرواؤ
- بند کرو
+ بند کرو
- تہاݙے فیڈبیک تے تھورائت ہیں!
+ تہاݙے فیڈبیک تے تھورائت ہیں!ݙاڈھا تسلی بخش
diff --git a/mobile/android/fenix/app/src/main/res/values-sl/strings.xml b/mobile/android/fenix/app/src/main/res/values-sl/strings.xml
index 9207394e10..96cc2722ca 100644
--- a/mobile/android/fenix/app/src/main/res/values-sl/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-sl/strings.xml
@@ -49,12 +49,20 @@
- Nedavno shranjeno
+ Nedavno shranjeno
- Prikaži vse shranjene zaznamke
+ Prikaži vse shranjene zaznamke
- Odstrani
+ Odstrani
+
+
+
+ Zaznamki
+
+ Prikaži vse zaznamke
+
+ Odstrani%1$s izdeluje Mozilla.
@@ -145,8 +153,10 @@
Nov zasebni zavihek
-
- Bližnjica do gesel
+
+ Gesla
+
+ Bližnjica do gesel
@@ -191,6 +201,10 @@
DodatkiRazširitve
+
+ Upravljanje razširitev
+
+ Odkrijte več razširitevPodatki o računu
@@ -209,18 +223,26 @@
Odpri v navadnem zavihkuDodaj na domač zaslon
+
+ Dodaj na domači zaslon …NamestiZnova sinhronizirajNajdi na strani
+
+ Najdi na strani …Prevedi stran
+ Shrani v zbirko …
+
Shrani v zbirkoDeli
+
+ Deli …Odpri v %1$su
@@ -248,9 +270,47 @@
Prilagodi domačo stran
- Prijava
-
- Sinhronizirajte gesla, zavihke in druge podatke
+ Prijava
+
+ Sinhronizirajte gesla, zavihke in druge podatke
+
+
+ Znova se prijavite za sinhronizacijo
+
+ Sinhroniziranje ustavljeno
+
+ Nov zasebni zavihek
+
+
+ Gesla
+
+ Novo v %1$su
+
+ Preklop na stran za računalnike
+
+ Orodja
+
+ Shrani
+
+
+ Dodaj stran med zaznamke
+
+ Uredi zaznamek
+
+ Shrani kot PDF …
+
+ Vklopi bralni pogled
+
+ Izklopi bralni pogled
+
+ Prevedi stran …
+
+ Prevedeno v jezik %1$s
+
+ Natisni …
@@ -348,8 +408,6 @@
Obvestilo o zasebnosti za Firefox
-
- Preberite več v obvestilu o zasebnostiZ veseljem skrbimo za vašo varnostJezik
+
+ Prevajanje
+
+ PrevajanjePodatkovne možnosti
@@ -624,6 +686,16 @@
Ni dovoljeno
+
+
+ Zahtevano
+
+ Izbirno
+
+ Dovoli za vsa spletna mesta
+
+ Če tej razširitvi zaupate, ji lahko dodelite dovoljenje za vsako spletno mesto.
+
Zbirka dodatkov po meri
@@ -648,7 +720,9 @@
Skoči nazaj
- Nedavni zaznamki
+ Nedavni zaznamki
+
+ ZaznamkiNedavno obiskano
@@ -743,8 +817,6 @@
ZgodovinaZaznamki
-
- PrijaveGesla
@@ -772,8 +844,6 @@
and the third is the device model. -->
%1$s na %2$s %3$s
-
- Kreditne karticePlačilna sredstva
@@ -790,6 +860,14 @@
Zavihek iz naprave %s
+
+
+ Zaprtih %1$s zavihkov: %2$d
+
+ Prikaži nedavno zaprte zavihke
+
Izjeme
@@ -1365,6 +1443,8 @@
Zapri zasebne zavihke
+
+ Zaprem zasebne zavihke?Tapnite to obvestilo ali ga povlecite vstran, da zaprete zasebne zavihke.
@@ -1724,13 +1804,9 @@
To stran lahko preprosto dodate na svoj domači zaslon naprave za lažji dostop in hitrejše brskanje v načinu, podobnem aplikaciji.
-
- Prijave in geslaGesla
- Shranjevanje prijav in gesel
-
Shranjuj geslaVprašaj pred shranjevanjem
@@ -1747,46 +1823,27 @@
Izpolnjuj uporabniška imena in gesla v drugih aplikacijah na napravi.
-
- Dodaj prijavo
-
Dodaj geslo
-
- Sinhronizacija prijavSinhroniziraj gesla
-
- Sinhroniziraj prijave med napravamiSinhroniziraj gesla med napravami
-
- Shranjene prijaveShranjena gesla
- Tu se prikažejo prijave, ki jih shranite ali sinhronizirate v %s.
-
Gesla, ki jih boste shranili ali sinhronizirali v %su, bodo našteta tukaj. Vsa gesla so shranjena v šifrirani obliki.
-
- Več o Sync.Več o sinhronizacijiIzjeme
-
- Tu bodo prikazane prijave in gesla, ki niso shranjena.Za tukaj navedena mesta %s ne bo shranjeval gesel.
-
- Prijave in gesla za te strani ne bodo shranjene.Za ta spletna mesta %s ne bo shranjeval gesel.Izbriši vse izjeme
-
- Iskanje prijavIskanje gesel
@@ -1815,17 +1872,11 @@
Prikaži gesloSkrij geslo
-
- Odklenite za ogled shranjenih prijavOdklenite za ogled shranjenih gesel
- Zavarujte svoje prijave in gesla
-
Zavarujte shranjena gesla
- Nastavite vzorec za zaklepanje naprave, PIN ali geslo za zaščito pred dostopom do shranjenih prijav in gesel, če vašo napravo uporablja še kdo.
-
Nastavite vzorec za zaklepanje naprave, PIN ali geslo, da preprečite dostop do shranjenih gesel, če vašo napravo uporabi kdo drug.Pozneje
@@ -1845,9 +1896,6 @@
Času zadnje uporabe
-
- Meni razvrščanja prijav
-
Meni za razvrščanje gesel
@@ -1856,41 +1904,27 @@
Samodejno izpolnjevanjeNaslovi
-
- Kreditne karticePlačilna sredstva
- Shrani in samodejno izpolni kartice
-
Shranjuj in izpolnjuj plačilna sredstva
-
- Podatki so šifrirani%s šifrira vsa plačilna sredstva, ki jih shraniteSinhroniziraj kartice med napravamiSinhroniziraj kartice
-
- Dodaj kreditno karticoDodaj kartico
-
- Upravljanje shranjenih karticUpravljanje karticDodaj naslovUpravljanje naslovov
-
- Shranjuj in samodejno izpolnjuj nasloveShranjuj in izpolnjuj naslove
-
- Vključi podatke, kot so številke, e-poštni naslovi in naslovi za dostavoVključuje telefonske številke in e-poštne naslove
@@ -1914,7 +1948,7 @@
Izbriši kartico
- Ali ste prepričani, da želite izbrisati to kreditno kartico?
+ Izbrišem kartico?Izbriši
@@ -1927,24 +1961,15 @@
Shranjene kartice
-
- Vnesite veljavno številko kreditne kartice
-
Vnesite veljavno številko kartice
-
- Izpolnite to poljeDodajte imeOdklenite za ogled shranjenih kartic
- Zavarujte svoje kreditne kartice
-
Zavarujte shranjena plačilna sredstva
- Nastavite vzorec za zaklepanje naprave, PIN ali geslo za zaščito pred dostopom do kreditnih kartic, če vašo napravo uporablja še kdo.
-
Nastavite vzorec za zaklepanje naprave, PIN ali geslo, da preprečite dostop do plačilnih sredstev, če vašo napravo uporabi kdo drug.Nastavi zdaj
@@ -1953,9 +1978,6 @@
Odklenite svojo napravo
-
- Odklenite za uporabo shranjenih podatkov o kreditnih karticah
-
Odklenite za ogled shranjenih plačilnih sredstev
@@ -1964,12 +1986,6 @@
Uredi naslovUpravljanje naslovov
-
- Ime
-
- Drugo ime
-
- PriimekIme
@@ -1996,7 +2012,7 @@
Izbriši naslov
- Res želite izbrisati ta naslov?
+ Izbrišem ta naslov?Izbriši
@@ -2095,49 +2111,29 @@
IzbrišiUredi
-
- Ali ste prepričani, da želite izbrisati to prijavo?Ali ste prepričani, da želite izbrisati to geslo?IzbrišiPrekliči
-
- Možnosti prijaveMožnosti gesel
-
- Besedilno polje za urejanje spletnega naslova prijave.Besedilno polje za urejanje spletnega naslova.
-
- Besedilno polje za urejanje uporabniškega imena prijave.Besedilno polje za urejanje uporabniškega imena.
- Besedilno polje za urejanje gesla prijave.
-
Besedilno polje za urejanje gesla.
-
- Shrani spremembe v prijavo.Shrani spremembe.
-
- UrejanjeUredi geslo
-
- Dodaj novo prijavoDodaj geslo
-
- Zahtevano je gesloVnesite geslo
- Zahtevano je uporabniško ime
-
Vnesite uporabniško imeZahtevano je ime domene
@@ -2463,6 +2459,10 @@
Prevedem to stran?
+
+ Stran prevedena iz jezika %1$s v jezik %2$sPreskusite zasebno prevajanje v %1$su
@@ -2473,10 +2473,14 @@
Izvorni jezikCiljni jezik
+
+ Poskusi z drugim izvornim jezikomNe zdajPrikaži izvirnik
+
+ Naložena izvirna neprevedena stranKončano
@@ -2497,16 +2501,25 @@
%1$s žal še ni podprt jezik.
- Več o tem
+ Več o temPrevajanje …
+
+ Prenesem jezik ob varčevanju s podatki (%1$s)?
+
+
- Možnosti prevajanja
+ Možnosti prevajanja
+
+ Možnosti prevajanjaVedno ponudi prevod
@@ -2518,11 +2531,16 @@
Nikoli ne prevajaj tega spletnega mestaPreglasi vse druge nastavitve
+
+ Preglasi ponudbe za prevajanjeNastavitve prevajanjaO prevodih v %1$su
+
+ Nekatere nastavitve začasno niso na voljo.
+
Prevajanje
@@ -2544,6 +2562,9 @@
Samodejno prevajanje
+
+ Jezikov ni bilo mogoče naložiti. Poskusite znova pozneje.
+
Ponudi prevajanje (privzeto)
@@ -2562,6 +2583,14 @@
Nikoli ne prevajaj teh spletnih mest
+
+ Odstrani %1$s
+
+ Spletnih mest ni bilo mogoče naložiti. Poskusite znova pozneje.
+
+ Izbrišem %1$s?Izbriši
@@ -2591,6 +2620,14 @@
Izbrano
+
+ Izbrišem jezik %1$s (%2$s)?
+
+ Izbrišem vse jezike (%1$s)?Če izbrišete vse jezike, bo %1$s pri prevajanju v predpomnilnik naložil delne jezike.
@@ -2598,6 +2635,10 @@
Prekliči
+
+ Dele jezikov prenesemo v vaš predpomnilnik, da prevodi ostanejo zasebni.
+
+ Dele jezikov prenesemo, da prevodi ostanejo zasebni.Vedno prenesi tudi ob varčevanju s podatki
@@ -2612,12 +2653,19 @@
Orodja za razhroščevanjePojdi nazaj
+
+
+ Odpri predal za razhroščevanje
+
+
Orodja za zavihkeŠt. zavihkov
- Dejavni
+ Dejavni
+
+ DejavenNedejavni
@@ -2628,10 +2676,58 @@
Orodje za ustvarjanje zavihkovKoličina zavihkov, ki jih želite ustvariti
+
+ Besedilno polje je prazno
+
+ Vnesite pozitivno celo število
+
+ Vnesite število, večje od ničDodaj med dejavne zavihkeDodaj med nedejavne zavihkeDodaj med zasebne zavihke
+
+
+
+
+ Nadaljuj
+
+ Izpolnite anketo
+
+ Obvestilo o zasebnosti
+
+ Pošlji
+
+ Zapri
+
+ Hvala za vaše mnenje!
+
+
+ zelo zadovoljen/-na
+
+ zadovoljen/-na
+
+ neodločen/-a
+
+ nezadovoljen/-na
+
+ zelo nezadovoljen/-na
+
+
+
+ Odpri anketo
+
+ Zapri anketo
+
+ Zapri
+
+
+
+ Prijave
+
+ Trenutna domena: %s
+
+ Izbriši prijavo z uporabniškim imenom %s
diff --git a/mobile/android/fenix/app/src/main/res/values-sq/strings.xml b/mobile/android/fenix/app/src/main/res/values-sq/strings.xml
index e7f4179835..acd961e78c 100644
--- a/mobile/android/fenix/app/src/main/res/values-sq/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-sq/strings.xml
@@ -47,12 +47,20 @@
- Ruajtur së fundi
+ Ruajtur së fundi
- Shfaqi krejt faqerojtësit e ruajtur
+ Shfaqi krejt faqerojtësit e ruajtur
- Hiqe
+ Hiqe
+
+
+
+ Faqerojtës
+
+ Shfaqni krejt faqerojtësit
+
+ Hiqe%1$s prodhohet nga Mozilla.
@@ -190,6 +198,10 @@
ShtesaZgjerime
+
+ Administroni zgjerime
+
+ Zbuloni më tepër zgjerimeHollësi llogarie
@@ -208,6 +220,8 @@
Hape në skedë të rregulltShtoje te skena e Kreut
+
+ Shtoje te skena e Kreut…Instaloje
@@ -219,9 +233,13 @@
Përktheje faqen
+ Ruajeni në koleksion…
+
Ruaje në koleksionNdajeni me të tjerët
+
+ Ndajeni me të tjerët…Hape në %1$s
@@ -272,6 +290,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Ruaje
+
+ Faqeruajeni këtë faqe
+
+ Përpunoni faqerojtësin
+
+ Ruajeni si PDF…
+
+ Aktivizo Pamjen Lexues
+
+ Çaktivizo Pamjen Lexues
+
+ Përktheni faqen…
+
+ Përkthyer në %1$s
+
+ Shtypeni…
+
S’ka zgjerime këtu
@@ -578,7 +614,9 @@
Gjuhë
- Përkthim
+ Përkthim
+
+ PërkthimeZgjedhje për të dhënat
@@ -685,7 +723,9 @@
Hidhu mbrapa
- Faqerojtës së fundi
+ Faqerojtës së fundi
+
+ FaqerojtësVizituar së fundi
@@ -825,6 +865,14 @@
Skedë nga %s
+
+
+ Skeda %1$s të mbyllura: %2$d
+
+ Shihni skeda të mbyllura së fundi
+
Përjashtime
@@ -2509,6 +2557,8 @@
Jo taniShfaq origjinalin
+
+ U ngarkua faqe origjinale e papërkthyerU bë
@@ -2689,13 +2739,18 @@
Shko mbrapsht
+
+ Hap sirtar diagnostikimi
+
Mjete SkedashNumër skedash
- Aktive
+ Aktive
+
+ AktiveJoaktive
diff --git a/mobile/android/fenix/app/src/main/res/values-su/strings.xml b/mobile/android/fenix/app/src/main/res/values-su/strings.xml
index ca7114a3cb..47f4e76ee8 100644
--- a/mobile/android/fenix/app/src/main/res/values-su/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-su/strings.xml
@@ -198,6 +198,10 @@
ÉmbohÉksténsi
+
+ Atur émbohan
+
+ Singraykeun émbohan leuwih lobaIber akun
@@ -216,6 +220,8 @@
Buka dina tab biasaTambahkeun ka layar Tepas
+
+ Tambahkeun ka layar Tepas…Pasang
@@ -228,9 +234,13 @@
Tarjamahkeun kaca
+ Simpen koléksi…
+
Simpen kana koléksiBagikeun
+
+ Bagikeun…Buka di %1$s
@@ -281,6 +291,25 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Teundeun
+
+ Markahkeun ieu kaca
+
+ Édit markah
+
+ Simpen minangka PDF…
+
+ Hurungkeun Pamintonan Pamaca
+
+ Pareuman Pamintonan Pamaca
+
+ Tarjamahkeun kaca…
+
+
+ Ditarjamahkeun kana %1$s
+
+ Citak…
+
Euweuh éksténsi di dieu
@@ -379,8 +408,6 @@
Iber pripasi Firefox
-
- Ilikan deui iber privasi urangUrang resep ngajaga anjeun sangkan amanTrackers dipikawanoh? Diblokir otomatis. Ekstensi? Coba sakabéhna 700. PDFs? Pamaca anu diwangun ku urang ngajadikeun éta gampang diurus.
+
+ Browser anu dirojong kalawan nirlaba urang nulungan pikeun mahing pausahaan ngukuntit anjeun dina wéb. \n \n Diajar leuwih lengkep dina iber privasi urang.wawar pripasi
@@ -405,10 +434,19 @@
Moal wakaTetep énkripsi nalika anjeun luncat antara alat
+
+ Sabot anjeun asup jeung nyingkronkeun, anjeun téh leuwih aman. Firefox ngaénkripsi sandi anjeun, tetengger, jeung réa-réa deui.AsupMoal waka
+
+ Iber mantuan anjeun tetep aman jeung Firefox
+
+ Kirim tab kalawan aman antara parabot anjeun jeung téangan fitur privasi séjénna dina Firefox.Hurungkeun iber
@@ -495,6 +533,8 @@
Pameungpeuk Spanduk Réréméh
+
+ Cookie Banner Blocker dina panyungsian pribadiPareum jang ieu loka
@@ -512,9 +552,23 @@
Rekés dukungan dikirimKiwari loka teu didukung
+
+ Hurungkeun Pameungpeuk Spanduk Réréméh pikeun %1$s?
+
+ Pareuman Pameungpeuk Spanduk Réréméh pikeun %1$s?%1$s teu bisa otomatis nolak rekés réréméh dina ieu loka. Anjeun bisa ngirim rekés pikeun ngadukung ieu loka jaga.
+
+ Pareuman jeung %1$s bakal mupus cookies sarta ngamuat deui situs ieu. Ieu bisa ngaluarkeun anjeun atawa ngosongkeun carangka balanja.
+
+ Hurungkeun jeung %1$s bakal nyobaan nampik sakabéh spanduk cookie dina situs ieu kalawan otomatis.
+
+ %1$s cikénéh nampik réréméh pikeun anjeun
+
+
+ Saeutik gangguan, saeutik cookies ngukuntit anjeun dina situs ieu.
+
Otomatis nyoba nyambung ka loka maké protokol énkripsi HTTPS pikeun ngaronjatkeun kaamanan.
@@ -532,13 +586,17 @@
Situs aman teu sayaga
- Sigana, raramatlokana teu ngarojong HTTPs.
+ Sigana, raramatlokana teu ngarojong HTTPS.Nanging, bisa waé aya panyerang kalibet. Upama diteruskeun asup kana raramatlokana, anjeun ulah ngasupkeun émbaran sénsitip. Upama diteruskeun, mode Ngan-HTTPS bakal dipareuman samentawis pikeun éta loka.Aksésibilitas
+
+ Serper akun Mozilal kustomSerper Sync kustom
+
+ Akun Mozilla/Server Sync dirobah. Ngaluarkeun aplikasi pikeun nerapkeun parobahan…Akun
@@ -559,6 +617,10 @@
Sambungkeun deui pikeun neruskeun nyingkronkeunBasa
+
+ Tarjamah
+
+ TarjamahPilihan data
@@ -586,9 +648,16 @@
Otokumplit URLs
+
+ Saran ti sponsor
+
+ Pangrojong %1$s kalawan saran anu disponsoranSaran ti %1$s
+
+ Pundut saran tina wéb patali jeung panyungsian anjeunBuka tutumbu dina aplikasi
@@ -608,6 +677,12 @@
Émbohan
+
+ Éksténsi
+
+ Pasang panambah tina berkas
+
+ Pasang pangémboh tina berkasIber
@@ -616,9 +691,22 @@
Teu diidinan
+
+
+ Dibutuhkeun
+
+ Pilihan
+
+ Idinan pikeun sakabéh situs
+
+
+ Lamun anjeun percaya pangémboh ieu, anjeun bisa méré idin dina unggal situs.
+
Koléksi Émboh sakahayang
+
+ Koléksi Émboh sakahayangHeug
@@ -631,11 +719,16 @@
Koléksi Émboh geus dirobah. Kaluar ti aplikasi pikeun nerapkeun parobahan…
+
+ Koléksi Émboh geus dirobah. Kaluar ti aplikasi pikeun nerapkeun parobahan…
+
Asup deuiMarkah anyar
+
+ MarkahAnyar dianjangan
@@ -684,19 +777,41 @@
Langlang latar lianna
+
+
+ Aya add-on anyar
+
+
+ Aya add-on anyar yeuh
+
+ Pariksa 100+ pangémboh anyar anu ngamungkinkeun anjeun ngajadikeun Firefox sorangan.
+
+ Paluruh add-ons
+
+ Paluruh pangémboh
+
Add-on tumpur saheulaanan
+
+ Éksténsi saheulanaan dipareumanAya add-on anu mugen, matak teu stabil kana sistem. %1$s gagal nyobaan malikan deui add-onna.\n\nAdd-on moal dimimitian ulang dina rintakan anu ayeuna.\n\nMiceun atawa numpurkeun add-on bisa jadi menerkeun ieu masalah.Coba balikan deui add-on
+
+ Jalankeun deui éksténsiTuluykeun bari add-on tumpur
+
+ Tuluykeun bari add-on tumpur
+
Kokolakeun akun
+
+ Robah kecap aksés anjeun, atur pangumpulan data, atawa pupus akun anjeunSingkronkeun ayeuna
@@ -706,8 +821,8 @@
Markah
-
- Login
+
+ Kecap sandiBuka tab
@@ -732,8 +847,8 @@
and the third is the device model. -->
%1$s dina %2$s %3$s
-
- Kartu kiridit
+
+ Cara mayarAlamat
@@ -747,6 +862,14 @@
Tab ti %s
+
+
+ %1$s tab ditutup: %2$d
+
+ Témbongkeun tab nu anyar ditutup
+
Iwal
@@ -1319,6 +1442,11 @@
Tutup tab nyamuni
+
+ Tutup tab pribadi?
+
+ Toél atawa golosorkeun bewara ieu pikeun nutup tab pribadi.
+
Pamasaran
@@ -1371,6 +1499,8 @@
Tab nyamuni ditutupTab nyamuni ditutup
+
+ Data panyungsi dipupusBEDO
@@ -1561,6 +1691,8 @@
Sakabéh réréméh (bakal ngabalukarkeun raramatloka jadi teu bener)Kerem réréméh meuntas-loka
+
+ Béjakeun situs wéb sangkan henteu ngabagi & ngajual dataKontén palacak
@@ -1590,7 +1722,7 @@
Meungpeuk réréméh anu dipaké ku maskapé jaringan iklan jeung analitika pikeun ngumpulkeun data langlangan anjeun di loka anu kaanjangan.
- Total Cookie Protection ngerem réréméh dina loka anu keur dibuka sangkan teu bisa dipaké ku palacak kayaning jaringan iklan pikeun nunutur anjeun meuntas-loa.
+ Total Cookie Protection ngerem réréméh dina loka anu keur dibuka ku anjeun sangkan teu bisa dipaké ku palacak kayaning jaringan iklan pikeun nunutur anjeun meuntas-loa.Gurandil kripto
@@ -1680,9 +1812,9 @@
Anjeun bisa kalawan gampang nambahkeun ieu raramatloka kana layar Tepas ponsél pikeun aksés instan sarta maluruh leuwih gancang kawas muka aplikasi.
- Login jeung kecap sandi
+ Kecap sandi
- Teundeun login jeung kecap sandi
+ Simpen kecap sandiNaros keur neundeun
@@ -1697,30 +1829,30 @@
Eusian sandiasma jeung kecap sandi dina séjén aplikasi dina parabot anjeun.
-
- Tambahkeun login
+
+ Tambahan sandi
- Singkronkeun login
-
- Singkronkeun login di sakabéh parabot
-
- Login nu disimpen
+ Singkronkeun sandi
+
+ Singkronkeun sandi dina sakabéh parabot
+
+ Sandi nu disimpen
- Login anu diteundeun atawa disingkronkeun ka %s bakal némbongan di dieu.
-
- Leuwih jéntré ngeunaan Sync.
+ Sandi anu anjeun simpen atawa disingkronkeun kana %s bakal didaptarkeun di dieu. Sakumna kecap sandi anu disimpen ku anjeun téh diénkripsi.
+
+ Lenyepan ngeunaan singkronisasiIwal
-
- Login jeung kecap sandi anu teu diteundeun bakal ditémbongkeun di dieu.
-
- Login jeung kecap sandi moal diteundeun pikeun ieu loka.
+
+ %s moal nyimpen sandi pikeun situs anu didaptarkeun di dieu.
+
+ %s moal nyimpen sandi pikeun situs-situs ieu.Hapus sadaya pengecualian
-
- Paluruh login
+
+ Téangan kecap sandiLoka
@@ -1747,12 +1879,10 @@
Témbongkeun sandiSumputkeun sandi
-
- Buka konci pikeun nempo login anu diteundeun
+
+ Buka konci pikeun nempo sandi anu diteundeun
- Amankeun login jeung kecap sandi anjeun
-
- Jieun pola konci paranti, PIN, atawa kecap sandi pikeun ngajaga login jeung kecap sandi anu diteundeun bisi paranti anjeun dipaké batur.
+ Amankeun kecap sandi anjeun nu disimpenEngké
@@ -1768,37 +1898,39 @@
Panungtun dipaké
-
- Runtuykeun menu login
+
+
+ Nyortir ménu kecap sandiEusi otomatisAlamat
-
- Kartu kiridit
+
+ Cara mayar
- Simpen jeung otongeusi kartu
-
- Data diénkrip
+ Simpen jeung eusian cara mayar
+
+ %s énkripsi kabéh cara mayar anu disimpen ku anjeunSingkronkeun kartu di sakabeh parabotSingkronkeun kartu
-
- Tambah kartu kiridit
-
- Kokolakeun kartu anu diteundeun
+
+ Tambahan kartu
+
+ Atur kartuTambah alamatKokolakeun alamat
-
- Simpen jeung otongeusi alamat
-
- Kaasup émbaran sarupaning nomer, surélék, jeung alamat kirim
+
+ Simpen jeung eusian alamat
+
+
+ Sartakeun nomer telepon jeung alamat surélékTambah kartu
@@ -1819,7 +1951,7 @@
Hapus kartu
- Yakin anjeun rék mupus ieu kartu kiridit?
+ Pupus kartu?Hapus
@@ -1831,37 +1963,31 @@
Kartu disimpen
-
- Mangga lebetkeun nomer kartu kiridit anu sah
-
- Mangga eusian kolom ieu
+
+ Asupkeun nomer kartu anu sah
+
+ Tambahan ngaranBuka konci pikeun nempo kartu anu diteundeun
- Amankeun kartu kiridit anjeun
-
- Jieun pola konci paranti, PIN, atawa kecap sandi pikeun ngajaga kartu kiridit anu diteundeun bisi paranti anjeun dipaké batur.
+ Amankeun metode mayar anjeun anu disimpenSetél ayeunaEngké deuiBuka konci paranti anjeun
-
- Buka konci pikeun nganggo inpormasi kartu kiridit anu disimpen
+
+ Buka konci pikeun maké cara mayar anu disimpenTambah alamatRopéa alamatKokolakeun alamat
-
- Ngaran Hareup
-
- Ngaran Tengah
-
- Ngaran Tukang
+
+ NgaranAlamat Jalan
@@ -1886,7 +2012,7 @@
Hapus alamat
- Yakin rék mupus ieu alamat?
+ Pupus alamat ieu?Hapus
@@ -1984,32 +2110,34 @@
PupusÉdit
-
- Yakin rék mupus ieu login?
+
+ Yakin anjeun rék mupus ieu sandi?PupusBolay
-
- Pilihan asup log
-
- Widang téks éditeun pikeun alamat raramat login.
-
- Widang téks éditeun pikeun sandiasma login.
+
+ Pilihan sandi
+
+ Widang téks éditeun pikeun alamat raramat login.
+
+ Widang téks éditeun pikeun sandiasma login.
- Widang téks éditeun pikeun kecap sandi login.
-
- Teundeun parobahan login.
-
- Édit
-
- Tambahkeun login anyar
-
- Butuh kecap sandi
+ Widang téks éditeun pikeun sandi kecap.
+
+ Simpen parobahan.
+
+ Ropéa sandi
+
+ Tambahan sandi
+
+ Asupkeun sandi
- Kudu ngeusian sandiasma
+ Asupkeun ngaran pamakéKudu ngeusian ngaran host
+
+ Asupkeun kaca raramatSungsi sora
@@ -2104,6 +2232,9 @@
Pamaluruhan %s
+
+
+ Alihkeun panyungsi baku anjeunSetél tutumbu ti raramatloka, surélék, jeung surat pikeun muka otomatis dina Firefox.
@@ -2141,17 +2272,90 @@
Buka setélan
+
+
+ Pamariksa repiu
+
+ Repiu andelan
+
+ Campuran bahasan nu dipercaya jeung nu teu dipercaya
+
+ Repiu lain andelan
+
+ Kumaha kadar andelan ulasan ieu?
+
+ Peunteun disaluyukeun
+
+ Dumasarkana ulasan andelan
+
+ Sorot tina ulasan cikénéh
+
+ Kumaha urang nangtukeun kualitas ulasan
+
+ Leuwih jéntré ngeunaan %s.
+
+ kumaha %s nangtukeun kualitas ulasan
+
+ Setélan
+
+ Témbongkeun iklan dina pamariksa ténjoan
+
+ Lenyepan
+
+ Pareuman pamariksaan ténjoan
+
+ Leuwih tinimbanganIklan ku %s
+
+ Pamariksaan ulasan drojong ku %s%s ku Mozilla
+
+ Katerangan anyar pikeun dipariksa
+
+ Pariksa ayeuna
+
+ Ulasan tacan cukup
+
+ Lamun produk ieu leuwih loba ulasanana, urang bisa mariksa kualitasna.
+
+ Produk teu sadia
+
+ Laporan produk aya dina stok
+
+ Mariksa kualitas ulasan (%s)
+
+ Lilana ieu kira-kira 60 detik.
+
+ Hatur nuhun geus ngalaporkeun!
+
+ Urang henteu bisa mariksa ulasan ieu
+
+ béja nu arék datang
+
+ Analisis geus luyu nu jeung panganyarnaNgarti
+
+ Euweuh inpo nu sadia kiwari
+
+ Urang keur digawé pikeun ngabéréskeun masalah éta. Mangga pariksa engké deui.Euweuh sambungan jaringan
+
+ Pariksa sambungan jaringan anjeun terus cobaan muatkeun deui kacana.
+
+ Euweuh inpormasi ngeunaan ulasan ieu
+
+ Pariksa kualitas review
+
+ Cobaan pituduh ulasan produk urang nu dipercaya Leuwih teleb
+
+ wawar pripasikatangtuan maké
@@ -2166,11 +2370,38 @@
Béta
+
+ Buka pamariksa ténjoan
+
+ Tutup pamariksa ténjoan
+
+ %1$s tina 5 béntang
+
+ Témbongkeun leuwih saeutik
+
+ Pidangkeu leuwih réa
+
+ Kualitas
+
+ Harga
+
+ Pangiriman
+
+ Bungkusan jeung dedegan
+
+ Daya saing
+
+ "%s"
+
tilep
+
+ tilepbatek
+
+ batekbuka tutumbu pikeun leuwih teleb ngeunaan ieu koléksi
@@ -2178,9 +2409,245 @@
buka tutumbu pikeun ngalenyepan
+
+ %s, Judul
+
+ Tumbu
+
+ Tumbu sadia
+
+
+
+ Tarjamahkeun kaca ieu?
+
+ Kaca ditarjamahkeun tina %1$s ka %2$s
+
+ Coba tarjamahan pribadi dina %1$s
+
+
+
+ Pikeun privasi anjeun, tarjamahan moal kungsi ninggalkeun alat anjeun. Basa anyar jeung panghadéan sakeudeung deui datang! %1$s
+
+ Lenyepan
+
+ Tarjamahkeun tina
+
+ Tarjamahkeun kana
+
+ Cobaan basa sumber séjén
+
+ Moal waka
+
+ Témbongkeun aslina
+
+ Kaca asli teu ditarjamahkeun dimuat
+
+ Anggeus
+
+ Tarjamahkeun
+
+ Pecakan deui
+
+ Narjamahkeun
+
+ Narjamahkeun keur Dipigawé
+
+ Pilih basa
+
+ Aya masalah narjamahkeun. Pék cobaan deui.
+
+ Teu bisa ngamuat basa. Pariksa sambungan internét anjeun sarta cobaan deui.
+
+ Hampura, urang acan ngadukung %1$s.
+
+ Lenyepan
+
+ Narjamahkeun…
+
+ Unduh basa dina modeu irit data (%1$s)?
+
+
+
+
+ Pilihan Tarjamahan
+
+ Pilihan tarjamahan
+
+ Salawasna tawarkeun narjamahkeun
+
+ Salawasna tarjamahkeun %1$s
+
+ Ulah narjamahkeun %1$s deui
+
+ Ulah narjamahkeun deui situs ieu
+
+ Timpah sakabéh setelan séjén
+
+ Timpah tawaran pikeun narjamahkeun
+
+ Setélan tarjamahan
+
+ Ngeunaan tarjamahan dina %1$s
+
+ Tutup lambaran Tarjamahan
+
+ Sababaraha setélan samentara teu nyampak.
+
+
+
+ Tarjamah
+
+ Tawarkeun pikeun narjamahkeun sabot mungkin
+
+ Salawasna unduh basa dina modeu irit data
+
+ Préférénsi tarjamahan
+
+ Tarjamahan otomatis
+
+ Ulah narjamahkeun situs-situs ieu
+
+ Undeur basa-basa
+
+
+
+ Tarjamahan otomatis
+
+
+ Pilih basa pikeun ngatur préférénsi "salawasna tarjamahkeun" jeung "ulah pernah narjamahkeun".
+
+ Teu bisa ngamuat basa. Mangga pariksa engké deui.
+
+
+ Salawasna tarjamahkeun
+
+ Ulah narjamahkeun deui
+
+
+ Piceun %1$s
+
+ Pupus %1$s?
+
+ Pupus
+
+ Bolay
+
+
+
+ Undeur Basa-basa
+
+ Lenyepan
+
+ Basa nu sadia
+
+ diperlukeun
+
+ %1$s (%2$s)
+
+
+ Pupus
+
+ Bolay
+
+
+ Unduh sabot dina modeu irit data (%1$s)?
+
+ Salawasna unduh dina modeu irit data
+
+ Undeur
+
+ Undeur jeung tarjamahkeun
+
+ Bolay
+
+
+
+ Parabot Debug
+
+ Mundur
+
+
+
+ Pakakas Tab
+
+ Jumlah tab
+
+ Aktip
+
+ Aktip
+
+ Teu aktif
+
+ Salindungan
+
+ Jumlah
+
+ Alat nyieun tab
+
+ Tab kuantitas pikeun nyieun
+
+ Tambahkeun kana tab aktip
+
+ Tambahkeun kana tab teu aktip
+
+ Tambahkeun kana tab nyamuni
+
-
+
+ Tuluykeun
+
+ Lengkepan survéy ieu
+
+ Wawar Privasi
+
+ Kirimkeun
+
+ Tutup
+
+ Hatur nuhun pikeun jawaban anjeun!
+
+ Puas pisan
+
+
+ Sugema
+
+ Nétral
+
+ Teu sugema
+
+ Kacida teu sugema
+
+
+
+ Buka survéy
+
+ Tutup Survéy
+
+ Tutup
+
+
+
+ Asup log
+
+ Domain ayeuna: %s
+
+ Tambahan asup log palsu pikeun domain ieu
+
+ Pupus asup log maké ngaran pamaké %s
+
diff --git a/mobile/android/fenix/app/src/main/res/values-sv-rSE/strings.xml b/mobile/android/fenix/app/src/main/res/values-sv-rSE/strings.xml
index d8659fb4d9..d8339db68e 100644
--- a/mobile/android/fenix/app/src/main/res/values-sv-rSE/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-sv-rSE/strings.xml
@@ -202,6 +202,10 @@
TilläggTillägg
+
+ Hantera tillägg
+
+ Upptäck fler tilläggKontoinformation
@@ -220,6 +224,8 @@
Öppna i vanlig flikLägg till på startsidan
+
+ Lägg till på startskärmen…Installera
@@ -231,9 +237,13 @@
Översätt sida
+ Spara i samling…
+
Spara i samlingDela
+
+ Dela…Öppna i %1$s
@@ -289,6 +299,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Spara
+
+ Bokmärk denna sida
+
+ Redigera bokmärke
+
+ Spara som PDF…
+
+ Aktivera Läsvyn
+
+ Stäng av Läsvyn
+
+ Översätt sida…
+
+ Översatt till %1$s
+
+ Skriv ut…
+
Inga tillägg här
@@ -386,8 +414,6 @@
Firefox sekretessmeddelande
-
- Läs mer i vårt sekretessmeddelandeVi älskar att hålla dig säkerSpråk
- Översättning
+ Översättning
+
+ ÖversättningarDataalternativ
@@ -670,10 +698,6 @@
KrävsValfri
-
- Läsa och ändra webbplatsdata
-
- Ta bort webbplatsTillåt för alla webbplatser
@@ -800,8 +824,6 @@
HistorikBokmärken
-
- InloggningarLösenord
@@ -829,8 +851,6 @@
and the third is the device model. -->
%1$s på %2$s %3$s
-
- KreditkortBetalningsmetoder
@@ -846,6 +866,14 @@
Flik från %s
+
+
+ %1$s stängde %2$d flikar
+
+ Visa nyligen stängda flikar
+
Undantag
@@ -1780,13 +1808,9 @@
Du kan enkelt lägga till den här webbplatsen på enhetens startskärm för att få direktåtkomst och surfa snabbare med en appliknande upplevelse.
-
- Inloggningar och lösenordLösenord
- Spara inloggningar och lösenord
-
Spara lösenordFråga för att spara
@@ -1801,47 +1825,28 @@
Fyll i användarnamn och lösenord i andra appar på din enhet.
-
- Lägg till inloggning
-
Lägg till lösenord
-
- Synkronisera inloggningarSynkronisera lösenord
-
- Synkronisera inloggningar mellan enheterSynkronisera lösenord mellan enheter
-
- Sparade inloggningarSparade lösenord
- De inloggningar som du sparar eller synkroniserar till %s kommer att dyka upp här.
-
Lösenorden du sparar eller synkroniserar till %s kommer att listas här. Alla lösenord du sparar är krypterade.
-
- Läs mer om Sync.Läs mer om synkroniseringUndantag
-
- Inloggningar och lösenord som inte sparas visas här.%s kommer inte att spara lösenord för webbplatser som listas här.
-
- Inloggningar och lösenord sparas inte för dessa webbplatser.%s kommer inte att spara lösenord för dessa webbplatser.Ta bort alla undantag
-
- Sök inloggningarSök efter lösenord
@@ -1870,17 +1875,11 @@
Visa lösenordDölj lösenord
-
- Lås upp för att se dina sparade inloggningarLås upp för att se dina sparade lösenord
- Säkra dina inloggningar och lösenord
-
Säkra dina sparade lösenord
- Konfigurera enhetens låsmönster, PIN eller lösenord för att skydda dina sparade inloggningar och lösenord från åtkomst om någon annan har din enhet.
-
Konfigurera ett enhetslåsmönster, PIN-kod eller lösenord för att skydda dina sparade lösenord från åtkomst om någon annan använder din enhet.Senare
@@ -1897,8 +1896,6 @@
Namn (A-Ö)Senast använd
-
- Sortera inloggningsmenynMenyn sortera lösenord
@@ -1908,41 +1905,27 @@
AutofyllAdresser
-
- KreditkortBetalningsmetoder
- Spara och fyll i kreditkort automatiskt
-
Spara och fyll i betalningsmetoder
-
- Data är krypterad%s krypterar alla betalningsmetoder som du spararSynkronisera kort mellan enheterSynkronisera kort
-
- Lägg till kreditkortLägg till kort
-
- Hantera sparade kreditkortHantera kortLägg till adressHantera adresser
-
- Spara och fyll i adresser automatisktSpara och fyll i adresser
-
- Inkludera information som nummer, e-post och leveransadresserInkluderar telefonnummer och e-postadresser
@@ -1966,8 +1949,6 @@
Ta bort kort
- Är du säker på att du vill ta bort det här kreditkortet?
-
Ta bort kort?Ta bort
@@ -1981,24 +1962,15 @@
Sparade kreditkort
-
- Ange ett giltigt kreditkortsnummer
-
Ange ett giltigt kortnummer
-
- Fyll i det här fältetLägg till ett namnLås upp för att se dina sparade kreditkort
- Säkra dina kreditkort
-
Säkra dina sparade betalningsmetoder
- Konfigurera enhetens låsmönster, PIN eller lösenord för att skydda dina sparade kreditkort från åtkomst om någon annan har din enhet.
-
Konfigurera ett enhetslåsmönster, PIN-kod eller lösenord för att skydda dina sparade betalningsmetoder från att användas om någon annan har din enhet.Konfigurera nu
@@ -2007,9 +1979,6 @@
Lås upp din enhet
-
- Lås upp för att använda lagrad kreditkortsinformation
-
Lås upp för att använda sparade betalningsmetoder
@@ -2018,12 +1987,6 @@
Redigera adressHantera adresser
-
- Förnamn
-
- Mellannamn
-
- EfternamnNamn
@@ -2049,8 +2012,6 @@
Ta bort adress
-
- Är du säker på att du vill ta bort den här adressen?Ta bort den här adressen?
@@ -2150,49 +2111,29 @@
Ta bortRedigera
-
- Är du säker på att du vill ta bort den här inloggningen?Är du säker på att du vill ta bort det här lösenordet?Ta bortAvbryt
-
- InloggningsalternativLösenordsalternativ
-
- Det redigerbara textfältet för inloggningens webbadress.Det redigerbara textfältet för webbplatsadressen.
-
- Det redigerbara textfältet för inloggningens användarnamn.Det redigerbara textfältet för användarnamnet.
- Det redigerbara textfältet för inloggningens lösenord.
-
Det redigerbara textfältet för lösenordet.
-
- Spara ändringar för inloggning.Spara ändringar.
-
- RedigeraRedigera lösenord
-
- Lägg till ny inloggningLägg till lösenord
-
- Lösenord krävsAnge ett lösenord
- Användarnamn krävs
-
Ange ett användarnamnVärdnamn krävs
@@ -2600,6 +2541,9 @@
Stäng översättningsarket
+
+ Vissa inställningar är inte tillgängliga för tillfället.
+
Översättningar
@@ -2622,6 +2566,9 @@
Välj ett språk för att hantera inställningarna för "översätt alltid" och "översätt aldrig".
+
+ Det gick inte att ladda språk. Kom tillbaka senare.
+
Erbjuda att översätta (standard)
@@ -2644,6 +2591,8 @@
Ta bort %1$s
+
+ Det gick inte att ladda webbplatser. Kom tillbaka senare.Tog bort %1$s?
@@ -2721,13 +2670,18 @@
Navigera bakåt
+
+ Öppna felsökningslådan
+
FlikverktygAntal flikar
- Aktiv
+ Aktiv
+
+ AktivInaktiv
@@ -2738,6 +2692,16 @@
Verktyg för att skapa flikarAntal flikar att skapa
+
+ Textfältet är tomt
+
+ Ange endast positiva heltal
+
+ Ange ett nummer större än noll
+
+ Översteg det maximala antalet flikar (%1$s) som kan genereras i en operationLägg till i aktiva flikar
@@ -2754,11 +2718,11 @@
Sekretessmeddelande
- Skicka in
+ Skicka in
- Stäng
+ Stäng
- Tack för din feedback!
+ Tack för din feedback!Väldigt nöjd
@@ -2770,6 +2734,14 @@
Väldigt missnöjd
+
+
+ Öppna undersökning
+
+ Stäng undersökning
+
+ Stäng
+
Inloggningar
diff --git a/mobile/android/fenix/app/src/main/res/values-tg/strings.xml b/mobile/android/fenix/app/src/main/res/values-tg/strings.xml
index 35aaf65dd9..8e3c6c45a9 100644
--- a/mobile/android/fenix/app/src/main/res/values-tg/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-tg/strings.xml
@@ -1,7 +1,7 @@
- %s-и хусусӣ
+ Хусусӣ %s%s (Хусусӣ)
@@ -202,6 +202,10 @@
Ҷузъҳои иловагӣВасеъшавиҳо
+
+ Идоракунии васеъшавиҳо
+
+ Кашф кардани васеъшавиҳои бештарМаълумот дар бораи ҳисоби корбар
@@ -221,6 +225,8 @@
Кушодан дар варақаи одӣИлова кардан ба экрани асосӣ
+
+ Илова кардан ба экрани асосӣ…Насб кардан
@@ -232,9 +238,13 @@
Тарҷума кардани саҳифа
+ Нигоҳ доштан дар маҷмуа…
+
Нигоҳ доштан дар маҷмуаМубодила кардан
+
+ Мубодила…Кушодан дар %1$s
@@ -288,6 +298,25 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Нигоҳ доштан
+
+ Гузоштани хатбарак барои ин саҳифа
+
+ Таҳрир кардани хатбарак
+
+ Нигоҳ доштан ҳамчун PDF…
+
+ Фаъол кардани намоиши хонанда
+
+ Хомӯш кардани намоиши хонанда
+
+ Тарҷума кардани саҳифа…
+
+
+ Ба забони %1$s тарҷума шуд
+
+ Чоп кардан…
+
Дар ин ҷой ягон васеъшавӣ нест
@@ -384,8 +413,6 @@
Огоҳномаи махфияти «Firefox»
-
- Маълумоти бештар дар «Огоҳномаи махфияти мо»Мо нигоҳдории бехатарии шуморо дӯст медоремЗабон
- Тарҷума
+ Тарҷума
+
+ ТарҷумаҳоИнтихоби маълумот
@@ -665,10 +694,6 @@
Ҳатмӣ астИнтихобӣ аст
-
- Хониш ва тағйироти маълумоти сомона
-
- Нест кардани сомонаИҷозат барои ҳамаи сомонаҳо
@@ -797,8 +822,6 @@
ТаърихХатбаракҳо
-
- ВоридшавиҳоНиҳонвожаҳо
@@ -826,8 +849,6 @@
and the third is the device model. -->
%1$s дар %2$s %3$s
-
- Кортҳои кредитӣТарзҳои пардохт
@@ -843,6 +864,14 @@
Варақа аз %s
+
+
+ %2$d варақаи пӯшидашудаи «%1$s»
+
+ Дидани варақаҳои ба наздикӣ пӯшидашуда
+
Истисноҳо
@@ -1778,13 +1807,9 @@
Шумо метавонед ин сомонаро ба экрани асосии дастгоҳи худ ба осонӣ илова кунед, то ки ба он дастрасии фаврӣ дошта бошед ва бо таҷрибаи ба барнома монанд зудтар паймоиш кунед.
-
- Воридшавиҳо ва ниҳонвожаҳоНиҳонвожаҳо
- Нигоҳ доштани воридшавиҳо ва ниҳонвожаҳо
-
Нигоҳ доштани ниҳонвожаҳоБо пешниҳоди нигоҳдорӣ
@@ -1799,46 +1824,27 @@
Номи корбарон ва ниҳонвожаҳоро дар барномаҳои дигари дастгоҳи худ пур кунед.
-
- Илова кардани воридшавӣ
-
Илова кардани ниҳонвожа
-
- Воридшавиҳои ҳамоҳангшудаҲамоҳанг кардани ниҳонвожаҳо
-
- Ҳамоҳанг кардани воридшавиҳо байни дастгоҳҳоҲамоҳанг кардани ниҳонвожаҳо байни дастгоҳҳо
-
- Воридшавиҳои нигоҳдошташудаНиҳонвожаҳои нигоҳдошташуда
- Воридшавиҳое, ки шумо дар %s нигоҳ медоред ё ҳамоҳанг мекунед, дар ин ҷо нишон дода мешаванд.
-
Ниҳонвожаҳоеро, ки шумо нигоҳ медоред ё бо «%s» ҳамоҳанг месозед, дар ин рӯйхат нишон дода мешаванд. Ҳамаи ниҳонвожаҳое, ки шумо нигоҳ медоред, рамзгузорӣ карда мешаванд.
-
- Маълумоти бештар дар бораи ҳамоҳангсозӣМаълумоти бештар дар бораи ҳамоҳангсозӣИстисноҳо
-
- Воридшавиҳо ва ниҳонвожаҳое, ки нигоҳ дошта нашудаанд, дар ин ҷо нишон дошта мешаванд.«%s» барои сомонаҳое, ки дар ин рӯйхат нишон дода шудаанд, ниҳонвожаҳоро нигоҳ намедорад.
-
- Воридшавиҳо ва ниҳонвожаҳо барои сомонаҳои зерин нигоҳ дошта намешаванд.«%s» барои сомонаҳои зерин ниҳонвожаҳоро нигоҳ намедорад.Нест кардани ҳамаи истисноҳо
-
- Ҷустуҷӯи воридшавиҳоҶустуҷӯи ниҳонвожаҳо
@@ -1867,17 +1873,11 @@
Нишон додани ниҳонвожаПинҳон кардани ниҳонвожа
-
- Барои дидани воридшавиҳои нигоҳдошташуда, қулфро кушоедБарои дидани ниҳонвожаҳои нигоҳдошташуда, қулфро кушоед
- Воридшавиҳо ва ниҳонвожаҳои худро муҳофизат намоед
-
Ниҳонвожаҳои нигоҳдоштаро муҳофизат намоед
- Барои муҳофизат кардани воридшавиҳо ва ниҳонвожаҳои худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед.
-
Барои муҳофизат кардани ниҳонвожаҳои нигоҳдошташудаи худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед.Дертар
@@ -1895,9 +1895,6 @@
Истифодашудаи охирин
-
- Мураттаб кардани менюи воридшавиҳо
-
Менюи мураттабсозии ниҳонвожаҳо
@@ -1906,41 +1903,27 @@
Пуркунии худкорНишониҳо
-
- Кортҳои кредитӣТарзҳои пардохт
- Нигоҳ доштан ва ба таври худкор пур кардани кортҳо
-
Нигоҳ доштан ва пур кардани тарзҳои пардохт
-
- Маълумот рамзгузорӣ карда шуд«%s» ҳамаи тарзҳои пардохтеро, ки шумо нигоҳ медоред, рамзгузорӣ мекунадҲамоҳанг кардани кортҳо байни дастгоҳҳоҲамоҳанг кардани кортҳо
-
- Илова кардани корти кредитӣИлова кардани корт
-
- Идора кардани кортҳои нигоҳдошташудаИдоракунии кортҳоИлова кардани нишонӣИдоракунии нишониҳо
-
- Нигоҳ доштан ва ба таври худкор пур кардани нишониҳоНигоҳ доштан ва пур кардани нишониҳо
-
- Илова кардани маълумот монанди рақамҳо, нишониҳои почтаи электронӣ ва бурдарасонӣРақамҳои телефон ва нишониҳои почтаи электрониро дар бар мегирад
@@ -1965,8 +1948,6 @@
Нест кардани корт
- Шумо мутмаин ҳастед, ки мехоҳед ин корти кредитиро нест намоед?
-
Кортро нест мекунед?Нест кардан
@@ -1980,24 +1961,15 @@
Кортҳои нигоҳдошташуда
-
- Лутфан, рақами корти кредитии дурустро ворид намоед
-
Рақами корти дурустро ворид намоед
-
- Лутфан, ин майдонро пур кунедНомеро ворид намоедБарои дидани кортҳои нигоҳдошташуда, қулфро кушоед
- Кортҳои кредитии худро муҳофизат кунед
-
Тарзҳои пардохти нигоҳдоштаи худро муҳофизат намоед
- Барои муҳофизат кардани кортҳои кредитии нигоҳдошташудаи худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед.
-
Барои муҳофизат кардани тарзҳои пардохти нигоҳдошташудаи худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед.Ҳозир насб кунед
@@ -2005,8 +1977,6 @@
ДертарҚулфи дастгоҳи худро кушоед
-
- Барои истифодаи маълумоти кортҳои кредитии нигоҳдошташуда, қулфро кушоедБарои истифодаи тарзҳои пардохти нигоҳдоштаи худ, қулфро кушоед
@@ -2016,12 +1986,6 @@
Таҳрир кардани нишонӣИдоракунии нишониҳо
-
- Ном
-
- Номи падар
-
- НасабНом
@@ -2047,8 +2011,6 @@
Нест кардани нишонӣ
-
- Шумо мутмаин ҳастед, ки мехоҳед ин нишониро нест намоед?Ин нишониро нест мекунед?
@@ -2146,50 +2108,30 @@
Нест карданТаҳрир кардан
-
- Шумо мутмаин ҳастед, ки мехоҳед ин воридшавиро нест намоед?Шумо мутмаин ҳастед, ки мехоҳед ин ниҳонвожаро нест намоед?Нест карданБекор кардан
-
- Имконоти воридшавӣИнконоти ниҳонвожа
-
- Майдони матни таҳриршаванда барои нишонии сомонаи воридшавӣ.Майдони матни таҳриршаванда барои нишонии сомона.
-
- Майдони матни таҳриршаванда барои номи корбарии воридшавӣ.Майдони матни таҳриршаванда барои номи корбар.
- Майдони матни таҳриршаванда барои ниҳонвожаи воридшавӣ.
-
Майдони матни таҳриршаванда барои ниҳонвожа.
-
- Нигоҳ доштани тағйирот барои воридшавӣТағийротро нигоҳ медорад.
-
- Таҳрир карданТаҳрир кардани ниҳонвожа
-
- Илова кардани воридшавии навИлова кардани ниҳонвожа
-
- Ниҳонвожа лозим астНиҳонвожаеро ворид намоед
- Номи корбар лозим аст
-
Номи корбареро ворид намоедНоми сервер лозим аст
@@ -2600,6 +2542,9 @@
Пӯшидани саҳифаи тарҷума
+
+ Баъзе танзимот муваққатан дастнорасанд.
+
Тарҷумаҳо
@@ -2623,6 +2568,9 @@
Барои идоракунии хусусиятҳои «Ҳамеша тарҷума карда шавад» ва «Ҳеҷ вақт тарҷума карда нашавад» забонеро интихоб намоед.
+
+ Забонҳоро бор карда натавонист. Лутфан, баъдтар такрор кунед.
+
Тарҷума пешниҳод карда шавад (Ба таври пешфарз)
@@ -2645,6 +2593,8 @@
Тоза кардани «%1$s»
+
+ Сомонаҳоро бор карда натавонист. Лутфан, баъдтар такрор кунед.«%1$s»-ро нест мекунед?
@@ -2722,13 +2672,18 @@
Ба қафо гузаштан
+
+ Кушодани менюи таҳиякунандаи ислоҳи хатоҳо
+
Абзорҳои варақаҳоШумораи варақаҳо
- Фаъол
+ Фаъол
+
+ ФаъолҒайрифаъол
@@ -2739,6 +2694,16 @@
Абзори эҷоди варақаҳоШумораи варақаҳое, ки эҷод карда мешаванд
+
+ Майдони матн холӣ аст
+
+ Лутфан, танҳо ададҳои бутуни мусбатро ворид кунед
+
+ Лутфан, рақамеро зиёда аз сифр ворид намоед
+
+ Шумораи ҳадди аксари варақаҳое (%1$s), ки дар як амалиёт эҷод карда мешаванд, зиёд шудИлова кардан ба варақаҳои фаъол
@@ -2755,12 +2720,12 @@
Огоҳномаи махфият
- Пешниҳод кардан
+ Пешниҳод кардан
- Пӯшидан
+ Пӯшидан
- Ташаккур барои изҳори назари шумо!
+ Ташаккур барои изҳори назари шумо!Хеле қаноатманд
@@ -2773,6 +2738,14 @@
Хеле дарғазаб
+
+
+ Кушодани саволнома
+
+ Пӯшидани саволнома
+
+ Пӯшидан
+
Воридшавиҳо
diff --git a/mobile/android/fenix/app/src/main/res/values-tr/strings.xml b/mobile/android/fenix/app/src/main/res/values-tr/strings.xml
index 45d931495b..48587d9d04 100644
--- a/mobile/android/fenix/app/src/main/res/values-tr/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-tr/strings.xml
@@ -200,6 +200,10 @@
EklentilerUzantılar
+
+ Uzantıları yönet
+
+ Daha fazla uzantı keşfetHesap bilgileri
@@ -218,6 +222,8 @@
Normal sekmede açAna ekrana ekle
+
+ Ana ekrana ekle…Yükle
@@ -229,9 +235,13 @@
Sayfayı çevir
+ Koleksiyona kaydet…
+
Koleksiyona kaydetPaylaş
+
+ Paylaş…%1$s ile aç
@@ -285,6 +295,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Kaydet
+
+ Sayfayı yer imlerine ekle
+
+ Yer imini düzenle
+
+ PDF olarak kaydet…
+
+ Okuyucu görünümünü aç
+
+ Okuyucu görünümünü kapat
+
+ Sayfayı çevir…
+
+ %1$s diline çevrildi
+
+ Yazdır…
+
Şu anda uzantı yok
@@ -382,8 +410,6 @@
Firefox gizlilik bildirimi
-
- Ayrıntıları gizlilik bildirimimizde bulabilirsinizSizi güvende tutmayı seviyoruzDil
- Çeviri
+ Çeviri
+
+ ÇevirilerVeri seçenekleri
@@ -667,10 +695,6 @@
Gerekliİsteğe bağlı
-
- Web sitesi verilerini okuma ve değiştirme
-
- Siteyi silTüm siteler için izin ver
@@ -795,8 +819,6 @@
GeçmişYer imleri
-
- HesaplarParolalar
@@ -823,8 +845,6 @@
and the third is the device model. -->
%1$s - %2$s %3$s
-
- Kredi kartlarıÖdeme yöntemleri
@@ -840,6 +860,14 @@
%s üzerinden gelen sekme
+
+
+ %2$d %1$s sekmesi kapatıldı
+
+ Son kapatılan sekmeleri göster
+
İstisnalar
@@ -1769,13 +1797,9 @@
Bu siteyi cihazınızın ana ekranına ekleyerek ona hızlıca erişebilir, site bir uygulamaymış gibi daha hızlı gezinti yapabilirsiniz.
-
- Hesaplar ve parolalarParolalar
- Kullanıcı adı ve parolaları kaydet
-
Parolaları kaydetKaydetmeyi sor
@@ -1790,46 +1814,27 @@
Cihazınızdaki diğer uygulamalarda kullanıcı adı ve parolalar doldurulsun.
-
- Hesap ekle
-
Parola ekle
-
- Hesapları eşitleParolaları eşitle
-
- Hesapları cihazlar arasında eşitleParolaları cihazlar arasında eşitle
-
- Kayıtlı hesaplarKayıtlı parolalar
- Kaydettiğiniz veya %s ile eşitlediğiniz hesaplar burada görünecektir.
-
%s tarayıcısına kaydettiğiniz veya eşitlediğiniz parolalar burada listelenecektir. Kaydettiğiniz tüm parolalar şifrelenir.
-
- Sync hakkında bilgi alın.Eşitlemeyle ilgili bilgi alİstisnalar
-
- Kaydedilmeyen hesaplar ve parolalar burada görünecektir.%s, burada listelenen sitelerin parolalarını kaydetmeyecektir.
-
- Bu sitelere ait hesaplar ve parolalar kaydedilmeyecektir.%s bu sitelerin parolalarını kaydetmeyecektir.Tüm istisnaları sil
-
- Hesaplarda araParolalarda ara
@@ -1858,17 +1863,11 @@
Parolayı gösterParolayı gizle
-
- Kayıtlı hesaplarınızı görmek için kilidi açınKayıtlı parolalarınızı görmek için kilidi açın
- Hesaplarınızı güvence altına alın
-
Kayıtlı parolalarınızı güvence altına alın
- Cihazınız başka birinin eline geçerse kayıtlı hesaplarına erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın.
-
Cihazınız başka birinin eline geçerse kayıtlı parolalarınıza erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın.Daha sonra
@@ -1886,8 +1885,6 @@
Ad (A-Z)Son kullanım
-
- Hesapları sırala menüsüParolaları sırala menüsü
@@ -1897,41 +1894,27 @@
Otomatik doldurmaAdresler
-
- Kredi kartlarıÖdeme yöntemleri
- Kartları kaydedip otomatik doldur
-
Ödeme yöntemlerini kaydet ve doldur
-
- Veriler şifrelenir%s kaydettiğiniz tüm ödeme yöntemlerini şifrelerKartları cihazlar arasında eşitleKartları eşitle
-
- Kredi kartı ekleKart ekle
-
- Kayıtlı kartları yönetKartları yönetAdres ekleAdresleri yönet
-
- Adresleri kaydedip otomatik doldurAdresleri kaydet ve doldur
-
- Numaralar, e-posta ve gönderim adresleri gibi bilgileri dahil etTelefon numaraları ve e-posta adresleri de dahildir
@@ -1955,8 +1938,6 @@
Kartı sil
- Bu kredi kartını silmek istediğinizden emin misiniz?
-
Kart silinsin mi?Sil
@@ -1970,24 +1951,15 @@
Kayıtlı kartlar
-
- Lütfen geçerli bir kredi kartı numarası girin
-
Geçerli bir kart numarası girin
-
- Lütfen bu alanı doldurunAdınızı yazınKayıtlı kartlarınızı görmek için kilidi açın
- Kredi kartlarını güvence altına al
-
Kayıtlı ödeme yöntemlerinizi güvence altına alın
- Cihazınız başka birinin eline geçerse kayıtlı kartlarınıza erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın.
-
Cihazınız başka birinin eline geçerse kayıtlı ödeme yöntemlerinize erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın.Hemen ayarla
@@ -1996,8 +1968,6 @@
Cihazınızın kilidini açın
-
- Depolanan kredi kartı bilgilerini kullanmak için kilidi açınKayıtlı ödeme yöntemlerinizi kullanmak için kilidi açın
@@ -2007,12 +1977,6 @@
Adresi düzenleAdresleri yönet
-
- Ad
-
- İkinci ad
-
- SoyadıAd
@@ -2038,8 +2002,6 @@
Adresi sil
-
- Bu adresi silmek istediğinizden emin misiniz?Bu adres silinsin mi?
@@ -2138,49 +2100,29 @@
SilDüzenle
-
- Bu hesabı silmek istediğinizden emin misiniz?Bu parolayı silmek istediğinizden emin misiniz?SilVazgeç
-
- Hesap seçenekleriParola seçenekleri
-
- Hesabın web adresi için düzenlenebilir metin alanı.Web sitesi adresi için düzenlenebilir metin alanı.
-
- Hesabın kullanıcı adı için düzenlenebilir metin alanı.Kullanıcı adı için düzenlenebilir metin alanı.
- Hesabın parolası için düzenlenebilir metin alanı.
-
Parola için düzenlenebilir metin alanı.
-
- Değişiklikleri hesaba kaydet.Değişiklikleri kaydet.
-
- DüzenleParola düzenle
-
- Yeni hesap ekleParola ekle
-
- Parola gerekliParolayı girin
- Kullanıcı adı gereklidir
-
Kullanıcı adını girinSunucu gereklidir
@@ -2590,6 +2532,9 @@
Çeviriler sayfasını kapat
+
+ Bazı ayarlar geçici olarak kullanılamıyor.
+
Çeviriler
@@ -2614,6 +2559,9 @@
”Her zaman çevir“ ve ”asla çevirme“ tercihlerini yönetmek için bir dil seçin.
+
+ Diller yüklenemedi. Lütfen daha sonra yeniden deneyin.
+
Çevirmeyi öner (varsayılan)
@@ -2637,6 +2585,8 @@
%1$s sitesini kaldır
+
+ Siteler yüklenemedi. Lütfen daha sonra yeniden deneyin.%1$s silinsin mi?
@@ -2715,13 +2665,18 @@
Geri git
+
+ Hata ayıklama bölmesini aç
+
Sekme araçlarıSekme sayısı
- Aktif
+ Aktif
+
+ AktifPasif
@@ -2732,6 +2687,16 @@
Sekme oluşturma aracıOluşturulacak sekme sayısı
+
+ Metin alanı boş
+
+ Lütfen yalnızca pozitif tamsayı girin
+
+ Lütfen sıfırdan büyük bir sayı girin
+
+ Tek bir işlemde oluşturulabilecek maksimum sekme sayısı (%1$s) aşıldıAktif sekmelere ekle
@@ -2748,11 +2713,11 @@
Gizlilik Bildirimi
- Gönder
+ Gönder
- Kapat
+ Kapat
- Geri bildiriminiz için teşekkürler!
+ Geri bildiriminiz için teşekkürler!Çok memnunum
@@ -2764,6 +2729,14 @@
Hiç memnun değilim
+
+
+ Anketi aç
+
+ Anketi kapat
+
+ Kapat
+
Hesaplar
diff --git a/mobile/android/fenix/app/src/main/res/values-ug/strings.xml b/mobile/android/fenix/app/src/main/res/values-ug/strings.xml
index 08c92ff266..2c820c15c1 100644
--- a/mobile/android/fenix/app/src/main/res/values-ug/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-ug/strings.xml
@@ -199,6 +199,10 @@
قوشۇلماكېڭەيتمە
+
+ كېڭەيتىلمە باشقۇرۇش
+
+ تېخىمۇ كۆپ كېڭەيتمە بايقاھېسابات ئۇچۇرى
@@ -217,6 +221,8 @@
ئادەتتىكى بەتكۈچتە ئاچباش ئېكرانغا قوش
+
+ باش ئېكرانغا قوش…قاچىلاش
@@ -228,9 +234,13 @@
بەت تەرجىمىسى
+ يىغقۇچقا ساقلا…
+
يىغقۇچقا ساقلاھەمبەھىرلەش
+
+ ھەمبەھىر…%1$s دا ئاچ
@@ -281,6 +291,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
ساقلا
+
+ بۇ بەتنى خەتكۈچكە قوش
+
+ خەتكۈچ تەھرىر
+
+ PDF كە ساقلا…
+
+ ئوقۇرمەن كۆرۈنۈشىنى ئاچ
+
+ ئوقۇرمەن كۆرۈنۈشىنى تاقا
+
+ بەت تەرجىمىسى…
+
+ %1$s غا تەرجىمە قىلىندى
+
+ باس…
+
بۇ يەردە كېڭەيتمە يوق
@@ -374,8 +402,6 @@
Firefox شەخسىيەت ئۇقتۇرۇشى
-
- شەخسىيەت ئۇقتۇرۇشىنىڭ تەپسىلاتىنى ئوقۇڭبىخەتەرلىكىڭىزنى ساقلاشنى ياخشى كۆرىمىز
- تەرجىمە
+ تەرجىمە
+
+ تەرجىمەسانلىق مەلۇمات تاللاش
@@ -656,10 +684,6 @@
زۆرۈرتاللاشچان
-
- تور بېكەت سانلىق مەلۇماتىنى ئوقۇيدۇ ياكى ئۆزگەرتىدۇ
-
- تور بېكەت ئۆچۈرھەممە تور بېكەتكە يول قويىدۇ
@@ -786,8 +810,6 @@
تارىخخەتكۈچ
-
- كىرىشئىم
@@ -812,8 +834,6 @@
The first parameter is the application name, the second is the device manufacturer name
and the third is the device model. -->
%2$s %3$s دىكى %1$s
-
- ئىناۋەتلىك كارتاچىقىم قىلىش ئۇسۇلى
@@ -829,6 +849,14 @@
%s بەتكۈچى
+
+
+ %1$s بەتكۈچ تاقالدى: %2$d
+
+ يېقىندا تاقالغان بەتكۈچلەرنى كۆرسەت
+
مۇستەسنا
@@ -1754,13 +1782,9 @@
تېز سۈرئەتتە زىيارەت قىلىش ۋە ئەپكە ئوخشاش زىيارەت تۇيغۇسىغا ئېرىشىش ئۈچۈن، مەزكۇر تور بېكەتنى باش ئېكرانغا ئاسانلا قوشالايسىز.
-
- كىرىش ۋە ئىمئىم
- كىرىش ۋە ئىم ساقلا
-
ئىم ساقلاساقلاشنى سورا
@@ -1774,46 +1798,28 @@
باشقا ئەپلەردە ئاپتوماتىك تولدۇرىدۇئۈسكۈنىڭىزدىكى باشقا ئەپلەردە ئىشلەتكۈچى ئىسمى ۋە ئىمنى تولدۇرىدۇ.
-
- كىرىشنى قوشئىم قوش
-
- كىرىشنى قەدەمداشلائىم قەدەمداشلا
-
- ئۈسكۈنىلەر ئارا قەدەمداشلائىمنى ئۈسكۈنىلەر ئارا قەدەمداشلايدۇ
-
- ساقلانغان كىرىشساقلانغان ئىم
- سىز ساقلىغان كىرىش ياكى %s بىلەن بولغان قەدەمداش بۇ جايدا كۆرۈنىدۇ.
-
سىز ساقلىغان ياكى %s غا قەدەمداشلىغان ئىم بۇ يەردە كۆرسىتىلىدۇ. سىز ساقلىغان بارلىق ئىم مەخپىيلەشتۈرۈلگەن.
-
- قەدەمداش ھەققىدىكى تەپسىلاتلار.قەدەمداش ھەققىدىكى تەپسىلاتلارمۇستەسنا
-
- ساقلانمىغان كىرىش ۋە ئىم بۇ يەردە كۆرسىتىلىدۇ.بۇ جايدا كۆرسىتىلگەن تور بېكەتلەر ئۈچۈن %s ئىم ساقلىمايدۇ.
-
- بۇ تور بېكەتلەرنىڭ كىرىش ۋە ئىم ئۇچۇرلىرى ساقلانمايدۇ.بۇ تور بېكەتلەر ئۈچۈن %s ئىم ساقلىمايدۇ.ھەممە مۇستەسنالارنى ئۆچۈرىدۇ
-
- كىرىش خاتىرىسىنى ئىزدەپارول ئىزدەش
@@ -1843,17 +1849,11 @@
ئىم يوشۇر
-
- ساقلانغان كىرىشلىرىڭىزنى كۆرۈش ئۈچۈن قۇلۇپ ئېچىڭساقلانغان پارولىڭىزنى كۆرۈش ئۈچۈن قۇلۇپ ئېچىڭ
- كىرىش ۋە ئىمنى قوغدايدۇ
-
ساقلانغان ئىملىرىڭىز شىفىرلىنىدۇ
- ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان تىزىمغا كىرىش ئۇچۇرى ۋە ئىمنى زىيارەت قىلالمايدۇ.
-
ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان ئىملىرىڭىزنى زىيارەت قىلالمايدۇ.كېيىنچە
@@ -1871,8 +1871,6 @@
ئىسمى (A-Z)ئاخىرقى قېتىم ئىشلىتىلگەن
-
- كىرىش تىزىملىكىنى تەرتىپلەيدۇئىم تىزىملىكىنى تەرتىپلە
@@ -1882,40 +1880,26 @@
ئاپتوماتىك تولدۇرئادرېس
-
- ئىناۋەتلىك كارتاچىقىم قىلىش ئۇسۇلى
- كارتا ساقلاش ۋە ئاپتوماتىك تولدۇرۇش
-
چىقىم قىلىش ئۇسۇلىنى ساقلاپ ۋە تولدۇرىدۇ
-
- سانلىق مەلۇمات شىفىرلانغانسىز ساقلىغان بارلىق چىقىم قىلىش ئۇسۇللىرىنى %s شىفىرلايدۇكارتىنى ئۈسكۈنىلەر ئارا قەدەمداشلايدۇكارتا قەدەمداشلا
-
- ئىناۋەتلىك كارتا قوشكارتا قوش
-
- ساقلانغان كارتا باشقۇرۇشكارتا باشقۇرۇشئادرېس قوشئادرېس باشقۇرۇش
-
- ئادرېسلارنى ساقلاش ۋە ئاپتوماتىك تولدۇرۇشئادرېس ساقلاپ تولدۇرىدۇ
-
- سان، ئېلخەت ۋە توشۇش ئادرېسى قاتارلىق ئۇچۇرلارنى ئۆز ئىچىگە ئالىدۇتېلېفون نومۇرى ۋە ئېلخەت ئادرېسىنى ئۆز ئىچىگە ئالىدۇ
@@ -1939,8 +1923,6 @@
كارتىنى ئۆچۈر
- بۇ ئىناۋەتلىك كارتىنى راستىنلا ئۆچۈرەمسىز؟
-
كارتىنى ئۆچۈرەمدۇ؟ئۆچۈر
@@ -1952,24 +1934,16 @@
ۋاز كەچساقلانغان كارتا
-
- ئىناۋەتلىك كارتا نومۇرىنى كىرگۈزۈڭئىناۋەتلىك كارتا نومۇرى كىرگۈزۈلىدۇ
-
- بۇ بۆلەكنى تولدۇرۇڭئات قوشساقلانغان كارتىلىرىڭىزنى كۆرۈش ئۈچۈن قۇلۇپ ئېچىڭ
-
- ئىناۋەتلىك كارتىڭىزنى شىفىرلايدۇساقلانغان چىقىم قىلىش ئۇسۇللىرىڭىز شىفىرلىنىدۇ
- ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان ئىناۋەتلىك كارتىڭىزنى زىيارەت قىلالمايدۇ.
-
ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان چىقىم قىلىش ئۇسۇلىڭىزنى زىيارەت قىلالمايدۇ.ھازىر تەڭشە
@@ -1977,8 +1951,6 @@
كېيىنچەئۈسكۈنىڭىزنىڭ قۇلۇپىنى ئېچىڭ
-
- ساقلانغان ئىناۋەتلىك كارتا ئۇچۇرلىرىنى ئىشلىتىش ئۈچۈن قۇلۇپ ئېچىڭساقلانغان چىقىم قىلىش ئۇسۇلىنى ئىشلىتىش ئۈچۈن قۇلۇپ ئېچىڭ
@@ -1987,12 +1959,6 @@
ئادرېس تەھرىرئادرېس باشقۇرۇش
-
- ئىسمى
-
- ئوتتۇرا ئىسمى
-
- تەگئاتئىسمى
@@ -2018,8 +1984,6 @@
ئادرېس ئۆچۈر
- بۇ ئادرېسنى راستىنلا ئۆچۈرەمسىز؟
-
بۇ ئادرېسنى ئۆچۈرەمدۇ؟ئۆچۈر
@@ -2117,50 +2081,30 @@
ئۆچۈرتەھرىر
-
- بۇ كىرىشنى راستىنلا ئۆچۈرەمسىز؟بۇ ئىمنى راستىنلا ئۆچۈرەمسىز؟ئۆچۈرۋاز كەچ
-
- كىرىش تاللانمىلىرىئىم تاللانمىسى
-
- كىرىشنىڭ تور ئادرېسىنى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى.تور بېكەت ئادرېسىنىڭ تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى.
-
- كىرىشنىڭ ئىشلەتكۈچى ئىسمىنى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى.ئىشلەتكۈچى ئاتىنىڭ تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى.
- كىرىشنىڭ ئىمىنى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى.
-
ئىمنىڭ تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى.
-
- كىرىش ئۆزگەرتىشلىرىنى ساقلايدۇ.ئۆزگەرتىشلەرنى ساقلايدۇ.
-
- تەھرىرئىم تەھرىر
-
- يېڭى كىرىش قوشئىم قوش
-
- ئىم زۆرۈرئىم كىرگۈزۈلىدۇ
- ئىشلەتكۈچى ئىسمى زۆرۈر
-
ئىشلەتكۈچى ئاتى كىرگۈزۈلىدۇمۇلازىم ئىسمى زۆرۈر
@@ -2571,6 +2515,9 @@
تەرجىمە جەدۋىلىنى تاقا
+
+ بەزى تەڭشەكلەرنى ۋاقىتلىق ئىشلەتكىلى بولمايدۇ.
+
تەرجىمە
@@ -2594,6 +2541,9 @@
«ھەمىشە تەرجىمە قىل» ۋە «ھەرگىز تەرجىمە قىلما» مايىللىقىدىن باشقۇرىدىغان تىل تاللىنىدۇ.
+
+ تىلنى يۈكلىيەلمەيدۇ. كېيىن قايتا تەكشۈرۈڭ.
+
تەرجىمە قىلىش (كۆڭۈلدىكى)
@@ -2617,6 +2567,8 @@
%1$s نى چىقىرىۋەت
+
+ تور بېكەتنى يۈكلىيەلمەيدۇ. كېيىن قايتا تەكشۈرۈڭ. %1$s نى ئۆچۈرەمدۇ؟
@@ -2694,13 +2646,18 @@
كەينىگە قايت
+
+ سازلاش تارتمىسىنى ئاچ
+
بەتكۈچ قوراللىرىبەتكۈچ سانى
- ئاكتىپ
+ ئاكتىپ
+
+ ئاكتىپئىشلەتمىگەن
@@ -2711,6 +2668,16 @@
بەتكۈچ قۇرۇش قورالىقۇرىدىغان بەتكۈچ سانى
+
+ تېكىست بۆلىكى بوش
+
+ پەقەت مۇسپەت پۈتۈن سان كىرگۈزۈڭ
+
+ نۆلدىن چوڭ سان كىرگۈزۈڭ
+
+ بىر مەشغۇلاتتا ھاسىللايدىغان ئەڭ كۆپ بەتكۈچ (%1$s) سانىدىن ئېشىپ كەتتىئاكتىپ بەتكۈچكە قوش
@@ -2727,11 +2694,11 @@
شەخسىيەت ئۇقتۇرۇشى
- يوللا
+ يوللا
- تاقا
+ تاقا
- قايتۇرما ئىنكاسىڭىزغا رەھمەت!
+ قايتۇرما ئىنكاسىڭىزغا رەھمەت!بەك رازى
@@ -2744,6 +2711,14 @@
بەك نارازى
+
+
+ راي سىناشنى ئاچ
+
+ راي سىناشنى تاقا
+
+ تاقا
+
كىرىش
diff --git a/mobile/android/fenix/app/src/main/res/values-uk/strings.xml b/mobile/android/fenix/app/src/main/res/values-uk/strings.xml
index a03bc42b8b..0800dff8c6 100644
--- a/mobile/android/fenix/app/src/main/res/values-uk/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-uk/strings.xml
@@ -198,6 +198,10 @@
ДодаткиРозширення
+
+ Керувати розширеннями
+
+ Знайти більше розширеньВаш обліковий запис
@@ -217,6 +221,8 @@
Відкрити у звичайній вкладціДодати на головний екран
+
+ Додати на головний екран…Встановити
@@ -228,9 +234,13 @@
Перекласти сторінку
+ Зберегти до збірки…
+
Зберегти до збіркиПоділитися
+
+ Поділитися…Відкрити в %1$s
@@ -284,6 +294,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Зберегти
+
+ Додати сторінку до закладок
+
+ Редагувати закладку
+
+ Зберегти як PDF…
+
+ Увімкнути режим читання
+
+ Вимкнути режим читання
+
+ Перекласти сторінку…
+
+ Перекладено на %1$s
+
+ Друкувати…
+
Тут немає розширень
@@ -381,8 +409,6 @@
Положення про приватність Firefox
-
- Докладніше в нашому положенні про приватністьМи дбаємо про вашу безпекуМова
- Переклад
+ Переклад
+
+ ПерекладиВибір даних
@@ -668,10 +696,6 @@
Обов\'язковоНеобов\'язково
-
- Читати та змінювати дані вебсайту
-
- Видалити вебсайтДозволити для всіх сайтів
@@ -798,8 +822,6 @@
ІсторіюЗакладки
-
- ПароліПаролі
@@ -826,8 +848,6 @@
and the third is the device model. -->
%1$s на %2$s %3$s
-
- Кредитні карткиСпособи оплати
@@ -844,6 +864,14 @@
Вкладка з %s
+
+
+ Закрито вкладок %1$s: %2$d
+
+ Переглянути недавно закриті вкладки
+
Винятки
@@ -1771,13 +1799,9 @@
Ви можете легко додати цей вебсайт на головний екран вашого пристрою, щоб мати миттєвий доступ до нього і працювати швидше.
-
- ПароліПаролі
- Зберігати паролі
-
Зберігати пароліПитати про збереження
@@ -1792,48 +1816,29 @@
Заповнювати імена користувачів і паролі в інших програмах на цьому пристрої.
-
- Додати пароль
-
Додати пароль
-
- Синхронізація паролівСинхронізувати паролі
-
- Синхронізувати паролі між пристроямиСинхронізація паролів між пристроями
-
- Збережені пароліЗбережені паролі
- Тут з’являтимуться ваші збережені та синхронізовані з %s паролі.
-
Тут з\'являтимуться паролі, які ви зберігаєте чи синхронізуєте в %s. Усі паролі зашифровано.
-
- Докладніше про синхронізацію.Докладніше про синхронізаціюВинятки
-
- Не збережені паролі з’являтимуться тут.%s не зберігатиме паролі для вказаних тут сайтів.
-
- Паролі для цих сайтів не зберігатимуться.%s не зберігатиме паролі для цих сайтів.Видалити всі винятки
-
- Шукати пароліПошук паролів
@@ -1863,17 +1868,11 @@
Показати парольПриховати пароль
-
- Розблокуйте для перегляду збережених паролівРозблокуйте, щоб переглянути збережені паролі
- Захистіть свої паролі
-
Захистіть збережені паролі
- Встановіть графічний ключ, PIN-код чи пароль для захисту збережених паролів від інших, хто може отримати доступ до вашого пристрою.
-
Встановіть графічний ключ, PIN-код чи пароль для захисту збережених паролів від інших, хто може отримати доступ до вашого пристрою.Пізніше
@@ -1891,9 +1890,6 @@
Востаннє використано
-
- Меню впорядкування паролів
-
Меню сортування паролів
@@ -1902,41 +1898,27 @@
АвтозаповненняАдреси
-
- Кредитні карткиСпособи оплати
- Зберігати та автоматично заповнювати дані карток
-
Зберігати й заповнювати способи оплати
-
- Дані зашифровано%s шифрує всі збережені способи оплатиСинхронізувати картки між пристроямиСинхронізувати картки
-
- Додати кредитну карткуДодати картку
-
- Керувати збереженими карткамиКерувати карткамиДодати адресуКерувати адресами
-
- Зберігати та автоматично заповнювати адресиЗберігати й заповнювати адреси
-
- Включити дані, як-от номери, електронні адреси та адреси доставленняМістить номери телефонів і адреси електронної пошти
@@ -1960,8 +1942,6 @@
Видалити картку
- Ви впевнені, що хочете видалити цю кредитну картку?
-
Видалити картку?Видалити
@@ -1975,24 +1955,15 @@
Збережені картки
-
- Введіть дійсний номер кредитної картки
-
Введіть дійсний номер картки
-
- Будь ласка, заповніть це полеДодайте назвуРозблокуйте для перегляду збережених карток
- Захистіть свої банківські картки
-
Захистіть свої збережені способи оплати
- Встановіть графічний ключ, PIN-код чи пароль для захисту збережених банківських карток від інших, хто може отримати доступ до вашого пристрою.
-
Встановіть графічний ключ, PIN-код чи пароль для захисту збережених способів оплати від інших, хто може отримати доступ до вашого пристрою.Встановити
@@ -2001,9 +1972,6 @@
Розблокуйте свій пристрій
-
- Розблокуйте, щоб використовувати збережену інформацію про кредитну картку
-
Розблокуйте, щоб використати збережені способи оплати
@@ -2012,12 +1980,6 @@
Редагувати адресуКерувати адресами
-
- Ім’я
-
- По батькові
-
- ПрізвищеІм’я
@@ -2043,8 +2005,6 @@
Видалити адресу
-
- Ви дійсно хочете видалити цю адресу?Видалити цю адресу?
@@ -2144,49 +2104,29 @@
ВидалитиЗмінити
-
- Ви дійсно хочете видалити цей запис?Ви дійсно хочете видалити цей пароль?ВидалитиСкасувати
-
- Опції записуПараметри пароля
-
- Текстове поле для редагування вебадреси запису.Текстове поле для редагування адреси вебсайту.
-
- Текстове поле для редагування імені користувача запису.Текстове поле для редагування імені користувача.
- Текстове поле для редагування пароля запису.
-
Текстове поле для редагування пароля.
-
- Зберегти зміни.Зберегти зміни.
-
- ЗмінитиРедагувати пароль
-
- Додати новий парольДодати пароль
-
- Потрібен парольВведіть пароль
- Необхідно вказати ім’я користувача
-
Введіть ім’я користувачаНеобхідно вказати назву вузла
@@ -2594,6 +2534,9 @@
Закрити блок перекладів
+
+ Деякі налаштування тимчасово недоступні.
+
Переклади
@@ -2617,6 +2560,9 @@
Виберіть мову, щоб керувати налаштуваннями ”завжди перекладати“ та ”ніколи не перекладати“.
+
+ Не вдалося завантажити мови. Повторіть спробу пізніше.
+
Пропонувати переклад (типово)
@@ -2641,6 +2587,8 @@
Вилучити %1$s
+
+ Не вдалося завантажити сайти. Повторіть спробу пізніше.Видалити %1$s?
@@ -2718,13 +2666,18 @@
Перейти назад
+
+ Відкрити панель налагодження
+
Інструменти вкладкиКількість вкладок
- Активні
+ Активні
+
+ АктивніНеактивні
@@ -2735,6 +2688,16 @@
Інструмент створення вкладокКількість вкладок для створення
+
+ Текстове поле порожнє
+
+ Будь ласка, введіть лише додатні цілі числа
+
+ Будь ласка, введіть число більше нуля
+
+ Перевищено максимальну кількість вкладок (%1$s), яку можна створити за одну операціюДодати до активних вкладок
@@ -2751,11 +2714,11 @@
Повідомлення про приватність
- Надіслати
+ Надіслати
- Закрити
+ Закрити
- Дякуємо за ваш відгук!
+ Дякуємо за ваш відгук!Дуже задоволені
@@ -2767,6 +2730,14 @@
Дуже незадоволені
+
+
+ Відкрити опитування
+
+ Закрити опитування
+
+ Закрити
+
Паролі
diff --git a/mobile/android/fenix/app/src/main/res/values-vi/strings.xml b/mobile/android/fenix/app/src/main/res/values-vi/strings.xml
index 4b8cd97821..0428dce517 100644
--- a/mobile/android/fenix/app/src/main/res/values-vi/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-vi/strings.xml
@@ -199,6 +199,10 @@
Tiện íchTiện ích
+
+ Quản lý tiện ích
+
+ Khám phá tiện tích khácThông tin tài khoản
@@ -217,6 +221,8 @@
Mở trong thẻ thông thườngThêm vào màn hình chính
+
+ Thêm vào màn hình chính…Cài đặt
@@ -228,9 +234,13 @@
Dịch trang
+ Lưu vào bộ sưu tập…
+
Lưu vào bộ sưu tậpChia sẻ
+
+ Chia sẻ…Mở bằng %1$s
@@ -283,6 +293,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
Lưu
+
+ Đánh dấu trang này
+
+ Chỉnh sửa dấu trang
+
+ Lưu dưới dạng PDF…
+
+ Bật chế độ đọc sách
+
+ Tắt chế độ đọc sách
+
+ Dịch trang…
+
+ Đã dịch sang %1$s
+
+ In…
+
Không có tiện ích ở đây
@@ -379,8 +407,6 @@
Thông báo về quyền riêng tư Firefox
-
- Tìm hiểu thêm trong thông báo bảo mật của chúng tôiChúng tôi thích giữ an toàn cho bạnNgôn ngữ
- Dịch
+ Dịch
+
+ DịchLựa chọn dữ liệu
@@ -662,10 +690,6 @@
Bắt buộcKhông bắt buộc
-
- Đọc và thay đổi dữ liệu trang web
-
- Xóa trang webCho phép tất cả các trang web
@@ -790,8 +814,6 @@
Lịch sửDấu trang
-
- Đăng nhậpMật khẩu
@@ -818,8 +840,6 @@
and the third is the device model. -->
%1$s trên %2$s %3$s
-
- Thẻ tín dụngPhương thức thanh toán
@@ -836,6 +856,14 @@
Thẻ từ %s
+
+
+ %2$d thẻ %1$s đã đóng
+
+ Xem thẻ đã đóng gần đây
+
Ngoại lệ
@@ -1754,13 +1782,9 @@
Bạn có thể dễ dàng thêm trang web vào màn hình chính thiết bị của bạn để có thể truy cập và duyệt web nhanh hơn với trải nghiệm giống như trên ứng dụng.
-
- Thông tin đăng nhập và mật khẩuMật khẩu
- Lưu thông tin đăng nhập và mật khẩu
-
Lưu mật khẩuYêu cầu để lưu
@@ -1775,47 +1799,28 @@
Điền tên người dùng và mật khẩu vào các ứng dụng khác trên thiết bị của bạn.
-
- Thêm thông tin đăng nhập
-
Thêm mật khẩu
-
- Đồng bộ hóa thông tin đăng nhậpĐồng bộ mật khẩu
-
- Đồng bộ hóa thông tin đăng nhập trên các thiết bịĐồng bộ hóa mật khẩu giữa các thiết bị
-
- Thông tin đăng nhập đã lưuMật khẩu đã lưu
- Thông tin đăng nhập bạn lưu hoặc đồng bộ hóa với %s sẽ hiển thị tại đây.
-
Mật khẩu bạn lưu hoặc đồng bộ hóa với %s sẽ được liệt kê ở đây. Tất cả mật khẩu bạn lưu đều được mã hóa.
-
- Tìm hiểu thêm về đồng bộ hóa.Tìm hiểu thêm về đồng bộ hoáNgoại lệ
-
- Thông tin đăng nhập và mật khẩu không được lưu sẽ được hiển thị ở đây.%s sẽ không lưu mật khẩu cho các trang được liệt kê ở đây.
-
- Thông tin đăng nhập và mật khẩu sẽ không được lưu cho các trang web này.%s sẽ không lưu mật khẩu cho các trang web này.Xóa tất cả ngoại lệ
-
- Tìm thông tin đăng nhậpTìm kiếm mật khẩu
@@ -1844,17 +1849,11 @@
Hiện mật khẩuẨn mật khẩu
-
- Mở khóa để xem thông tin đăng nhập đã lưu của bạnMở khóa để xem mật khẩu đã lưu của bạn
- Bảo mật thông tin đăng nhập và mật khẩu của bạn
-
Giữ mật khẩu đã lưu của bạn một cách an toàn
- Thiết lập mẫu khóa thiết bị, mã PIN hoặc mật khẩu để bảo vệ thông tin đăng nhập và mật khẩu đã lưu của bạn khỏi bị truy cập nếu người khác lấy được thiết bị của bạn.
-
Đặt mật khẩu thiết bị dạng mẫu hình, mã PIN hoặc mật khẩu để bảo vệ mật khẩu đã lưu của bạn không bị truy cập nếu người khác lấy được thiết bị của bạn.Để sau
@@ -1871,8 +1870,6 @@
Tên (A-Z)Sử dụng lần cuối
-
- Sắp xếp menu đăng nhậpMenu sắp xếp mật khẩu
@@ -1882,41 +1879,27 @@
Tự động điềnĐịa chỉ
-
- Thẻ tín dụngPhương thức thanh toán
- Lưu và tự động điền thẻ tín dụng
-
Lưu và điền phương thức thanh toán
-
- Dữ liệu được mã hóa%s mã hóa tất cả các phương thức thanh toán bạn lưuĐồng bộ thông tin thẻ tín dụng trên các thiết bịĐồng bộ hóa thẻ tín dụng
-
- Thêm thẻ tín dụngThêm thẻ
-
- Quản lý thẻ tín dụng đã lưuQuản lý thẻ tín dụngThêm địa chỉQuản lý địa chỉ
-
- Lưu và tự động điền địa chỉLưu và điền địa chỉ
-
- Bao gồm thông tin như số, email và địa chỉ giao hàngBao gồm số điện thoại và địa chỉ email
@@ -1940,8 +1923,6 @@
Xóa thẻ
- Bạn có chắc chắn muốn xóa thẻ tín dụng này không?
-
Xoá thẻ?Xóa
@@ -1955,24 +1936,15 @@
Thẻ tín dụng đã lưu
-
- Vui lòng nhập số thẻ tín dụng hợp lệ
-
Nhập số thẻ hợp lệ
-
- Vui lòng điền vào trường nàyThêm tênMở khóa để xem các thẻ tín dụng đã lưu của bạn
- Bảo mật thẻ tín dụng của bạn
-
Giữ các phương thức thanh toán đã lưu của bạn một cách an toàn
- Thiết lập màn hình khóa thiết bị với mẫu hình, mã PIN hoặc mật khẩu để bảo vệ thẻ tín dụng đã lưu của bạn không bị truy cập nếu người khác có thiết bị của bạn.
-
Đặt mật khẩu thiết bị dạng mẫu hình, mã PIN hoặc mật khẩu để bảo vệ phương thức thanh toán đã lưu của bạn không bị truy cập nếu người khác lấy đuọc thiết bị của bạn.Thiết lập ngay
@@ -1980,8 +1952,6 @@
Để sauMở khóa thiết bị của bạn
-
- Mở khóa để sử dụng thông tin thẻ tín dụng được lưu trữMở khóa để sử dụng các phương thức thanh toán đã lưu
@@ -1991,12 +1961,6 @@
Sửa địa chỉQuản lý địa chỉ
-
- Tên
-
- Tên đệm
-
- HọTên
@@ -2022,8 +1986,6 @@
Xóa địa chỉ
-
- Bạn có chắc chắn muốn xóa địa chỉ này không?Xoá địa chỉ này?
@@ -2122,49 +2084,29 @@
XóaChỉnh sửa
-
- Bạn có chắc chắn muốn xóa thông tin đăng nhập này không?Bạn có chắc chắn muốn xóa mật khẩu này?XóaHủy bỏ
-
- Tùy chọn thông tin đăng nhậpCài đặt mật khẩu
-
- Trường văn bản có thể chỉnh sửa cho địa chỉ web của thông tin đăng nhập.Trường văn bản có thể chỉnh sửa cho địa chỉ trang web.
-
- Trường văn bản có thể chỉnh sửa cho tên người dùng của thông tin đăng nhập.Trường văn bản có thể chỉnh sửa cho tên người dùng.
- Trường văn bản có thể chỉnh sửa cho mật khẩu của thông tin đăng nhập.
-
Trường văn bản có thể chỉnh sửa cho mật khẩu.
-
- Lưu các thay đổi vào thông tin đăng nhập.Lưu thay đổi.
-
- Chỉnh sửaChỉnh sửa mật khẩu
-
- Thêm thông tin đăng nhập mớiThêm mật khẩu
-
- Yêu cầu mật khẩuNhập mật khẩu
- Yêu cầu tên đăng nhập
-
Nhập tên người dùngYêu cầu tên máy chủ
@@ -2512,6 +2454,8 @@
Không phải bây giờHiển thị bản gốc
+
+ Trang nguyên bản chưa dịch đã được tảiXong
@@ -2569,6 +2513,9 @@
Đóng bảng dịch
+
+ Một số cài đặt tạm thời không khả dụng.
+
Dịch
@@ -2592,6 +2539,9 @@
Hãy chọn một ngôn ngữ để quản lí các tùy chọn ”Luôn dịch“ và ”Không bao giờ dịch“.
+
+ Không thể tải ngôn ngữ. Vui lòng kiểm tra lại sau.
+
Đề xuất dịch (mặc định)
@@ -2615,6 +2565,8 @@
Xóa %1$s
+
+ Không thể tải trang web. Vui lòng kiểm tra lại sau.Xóa %1$s?
@@ -2692,13 +2644,18 @@
Điều hướng quay lại
+
+ Mở ngăn gỡ lỗi
+
Công cụ thẻSố lượng thẻ
- Hoạt động
+ Hoạt động
+
+ Đang hoạt độngKhông hoạt động
@@ -2709,6 +2666,16 @@
Công cụ tạo thẻSố lượng thẻ cần tạo
+
+ Trường văn bản đang trống
+
+ Vui lòng chỉ nhập số nguyên dương
+
+ Vui lòng nhập số lớn hơn 0
+
+ Đã vượt quá số lượng thẻ tối đa (%1$s) có thể được tạo ra trong một thao tácThêm vào thẻ đang hoạt động
@@ -2725,11 +2692,11 @@
Thông báo bảo mật
- Gửi
+ Gửi
- Đóng
+ Đóng
- Cảm ơn phản hồi của bạn!
+ Cảm ơn phản hồi của bạn!Rất hài lòng
@@ -2741,6 +2708,14 @@
Rất không hài lòng
+
+
+ Mở khảo sát
+
+ Đóng khảo sát
+
+ Đóng
+
Thông tin đăng nhập
diff --git a/mobile/android/fenix/app/src/main/res/values-zh-rCN/strings.xml b/mobile/android/fenix/app/src/main/res/values-zh-rCN/strings.xml
index 9d9182dcd4..9d92f3c32d 100644
--- a/mobile/android/fenix/app/src/main/res/values-zh-rCN/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-zh-rCN/strings.xml
@@ -204,6 +204,10 @@
附加组件扩展
+
+ 管理扩展
+
+ 探索更多扩展账户信息
@@ -222,6 +226,8 @@
在常规标签页中打开添加到主屏幕
+
+ 添加到主屏幕…安装
@@ -233,10 +239,14 @@
翻译页面
+ 保存到收藏集…
+
保存到收藏集分享
+
+ 分享…用 %1$s 打开
@@ -291,6 +301,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
保存
+
+ 将此页面加入书签
+
+ 编辑书签
+
+ 另存为 PDF…
+
+ 开启阅读模式
+
+ 关闭阅读视图
+
+ 翻译页面…
+
+ 已翻译成%1$s
+
+ 打印…
+
暂无扩展
@@ -390,8 +418,6 @@
Firefox 隐私声明
-
- 阅读我们的隐私声明详细了解我们乐于为您护航语言
- 翻译
+ 翻译
+
+ 翻译数据反馈
@@ -677,10 +705,6 @@
必需可选
-
- 读取和更改网站数据
-
- 删除网站允许在所有网站上运行
@@ -808,8 +832,6 @@
历史记录书签
-
- 登录信息密码
@@ -836,9 +858,6 @@
and the third is the device model. -->
%2$s %3$s 上的 %1$s
-
- 信用卡
-
付款方式
@@ -855,6 +874,14 @@
来自 %s 的标签页
+
+
+ 已关闭 %1$s 中的 %2$d 个标签页
+
+ 查看最近关闭的标签页
+
例外
@@ -1812,13 +1839,9 @@
您可以轻松将此网站添加到设备主屏幕,以便迅捷访问并以类似应用的体验畅享浏览。
-
- 密码密码
- 保存登录名和密码
-
保存密码询问是否保存
@@ -1835,47 +1858,28 @@
在您设备上的其他应用程序中填充用户名和密码。
-
- 添加登录信息
-
添加密码
-
- 同步登录信息同步密码
-
- 跨设备同步登录信息跨设备同步密码
-
- 保存的登录信息保存的密码
- 您保存或同步到 %s 的登录信息将显示于此处。
-
保存和同步到 %s 的密码会显示在这里,所有密码均已加密保存。
-
- 详细了解“同步”。详细了解同步功能例外
-
- 不保存登录名和密码的网站将显示于此处。%s 将不会保存此处所列网站的密码。
-
- 将不保存这些网站的登录名和密码。%s 将不会保存这些网站的密码。删除所有例外
-
- 搜索登录信息搜索密码
@@ -1904,17 +1908,11 @@
显示密码隐藏密码
-
- 解锁以查看您保存的登录信息解锁以查看保存的密码
- 保护您的登录名和密码
-
保护您保存的密码
- 设置设备锁定图案、PIN 或密码以保护您保存的登录名与密码,避免他人盗用。
-
设置设备锁定图案、PIN 或密码以保护您保存的密码,避免他人盗用。稍后
@@ -1931,8 +1929,6 @@
名称(A-Z)上次使用
-
- 排序登录信息菜单密码排序菜单
@@ -1942,41 +1938,27 @@
自动填充地址
-
- 信用卡付款方式
- 保存并自动填充信用卡信息
-
保存和填写付款方式
-
- 数据已加密%s 会加密您保存的所有付款方式跨设备同步信用卡信息同步卡片信息
-
- 添加信用卡添加信用卡
-
- 管理保存的卡片管理信用卡添加地址管理地址
-
- 保存并自动填充地址保存和填充地址
-
- 包含号码、邮箱和收货地址等信息包括电话号码和邮箱地址
@@ -2000,8 +1982,6 @@
删除卡片
- 您确定要删除此信用卡吗?
-
确定删除信用卡吗?删除
@@ -2015,25 +1995,16 @@
保存的卡片
-
- 请输入有效的信用卡卡号
-
请输入有效卡号
-
- 请填写此栏请输入持卡人姓名解锁后即可查看保存的卡片信息
-
- 保护您的卡片信息保护您保存的付款方式
- 设置设备锁定图案、PIN 或密码以保护您保存的卡片信息,避免他人盗用。
-
设置设备锁定图案、PIN 或密码以保护您保存的付款方式,避免他人盗用。立即设置
@@ -2042,9 +2013,6 @@
解锁设备
-
- 解锁以使用存储的卡片信息
-
解锁以使用保存的付款方式
@@ -2053,12 +2021,6 @@
编辑地址管理地址
-
- 名
-
- 中间名
-
- 姓姓名
@@ -2084,8 +2046,6 @@
删除地址
-
- 您确定要删除此地址吗?确定删除此地址吗?
@@ -2184,49 +2144,29 @@
删除编辑
-
- 您确定要删除此登录信息吗?您确定要删除此密码吗?删除取消
-
- 登录选项密码选项
-
- 登录信息中的网址输入框。网址输入框。
-
- 登录信息中的用户名输入框。用户名输入框。
- 登录信息中的密码输入框。
-
密码输入框。
-
- 保存编辑过的登录信息。保存更改。
-
- 编辑编辑密码
-
- 新建登录信息添加密码
-
- 需要密码请输入密码
- 用户名不能为空
-
请输入用户名主机名不能为空
@@ -2643,6 +2583,9 @@
关闭翻译表单
+
+ 部分设置暂时无法使用。
+
翻译
@@ -2665,6 +2608,9 @@
请选择语言来管理“总是翻译”和“永不翻译”首选项。
+
+ 无法加载语言包,请稍后再试。
+
询问是否翻译(默认)
@@ -2688,6 +2634,8 @@
移除 %1$s
+
+ 无法加载网站,请稍后再试。确定删除 %1$s 吗?
@@ -2765,13 +2713,18 @@
向前导航
+
+ 打开调试抽屉
+
标签页工具标签页数量
- 活跃
+ 活跃
+
+ 活跃休眠
@@ -2782,6 +2735,16 @@
标签页创建工具要创建的标签页数量
+
+ 文本框为空
+
+ 只能输入正整数
+
+ 只能输入大于 0 的数字
+
+ 超出单次操作所能生成的标签页数量上限(%1$s 个)添加到活跃标签页
@@ -2798,11 +2761,11 @@
隐私声明
- 提交
+ 提交
- 关闭
+ 关闭
- 感谢反馈!
+ 感谢反馈!非常满意
@@ -2815,6 +2778,14 @@
非常不满意
+
+
+ 打开问卷
+
+ 关闭问卷
+
+ 关闭
+
登录信息
diff --git a/mobile/android/fenix/app/src/main/res/values-zh-rTW/strings.xml b/mobile/android/fenix/app/src/main/res/values-zh-rTW/strings.xml
index fee537aaf9..1bec6b339b 100644
--- a/mobile/android/fenix/app/src/main/res/values-zh-rTW/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values-zh-rTW/strings.xml
@@ -202,6 +202,10 @@
附加元件擴充套件
+
+ 管理擴充套件
+
+ 探索更多擴充套件帳號資訊
@@ -220,6 +224,8 @@
用一般分頁開啟新增至裝置主畫面
+
+ 新增至裝置主畫面…安裝
@@ -231,9 +237,13 @@
翻譯頁面
+ 儲存至收藏集…
+
儲存至收藏集分享
+
+ 分享…使用 %1$s 開啟
@@ -289,6 +299,24 @@
bookmarking a page, saving to collection, shortcut or as a PDF, and adding to home screen -->
儲存
+
+ 將此頁加入書籤
+
+ 編輯書籤
+
+ 儲存為 PDF…
+
+ 開啟閱讀模式
+
+ 關閉閱讀模式
+
+ 翻譯此頁…
+
+ 已翻譯為%1$s
+
+ 列印…
+
這裡沒有擴充套件
@@ -386,8 +414,6 @@
Firefox 隱私權公告
-
- 可以到我們的隱私權公告了解更多資訊我們希望確保您上網安全語言
- 翻譯
+ 翻譯
+
+ 翻譯回報資料
@@ -671,10 +699,6 @@
必需非必要
-
- 讀取或變更網站資料
-
- 刪除網站允許所有網站
@@ -800,8 +824,6 @@
瀏覽紀錄書籤
-
- 登入資訊密碼
@@ -828,8 +850,6 @@
and the third is the device model. -->
在 %2$s %3$s 上的 %1$s
-
- 信用卡付款方式
@@ -846,6 +866,14 @@
來自 %s 的分頁
+
+
+ 已關閉 %1$s 分頁:%2$d
+
+ 檢視最近關閉的分頁
+
例外網站
@@ -1797,13 +1825,9 @@
您可將此網站加到裝置主畫面,方便快速開啟,或是以類似 App 的方式使用。
-
- 登入資訊與密碼密碼
- 儲存登入資訊與密碼
-
已存密碼詢問我是否儲存
@@ -1818,46 +1842,27 @@
使用其他裝置中的其他應用程式時也自動填寫使用者名稱與密碼。
-
- 新增登入資訊
-
新增密碼
-
- 同步登入資訊同步密碼
-
- 在不同裝置間同步登入資訊在不同裝置間同步密碼
-
- 儲存的登入資訊已存密碼
- 您儲存或同步到 %s 的登入資訊將顯示於此處。
-
您儲存或同步到 %s 的密碼將顯示於此處,所有儲存的密碼資訊都會被加密。
-
- 了解 Sync 的更多資訊。瞭解同步功能的更多資訊例外網站
-
- 不儲存登入資訊與密碼的網站將顯示於此處。%s 不會儲存下列網站的密碼。
-
- 將不儲存這些網站的登入資訊與密碼。%s 不會儲存下列網站的密碼。刪除所有例外
-
- 搜尋登入資訊搜尋密碼
@@ -1886,17 +1891,11 @@
顯示密碼隱藏密碼
-
- 解鎖後即可檢視儲存的登入資訊解鎖後即可檢視儲存的密碼
- 保護您的登入資訊與密碼
-
保護您儲存的密碼
- 設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存下來的登入資訊與密碼,避免別人盜用。
-
設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存的密碼,避免別人盜用。稍後處理
@@ -1913,8 +1912,6 @@
名稱(A-Z 排序)上次使用
-
- 排序登入資訊選單排序密碼選單
@@ -1924,42 +1921,28 @@
自動填寫地址
-
- 信用卡付款方式
- 儲存並自動填寫卡片
-
儲存並自動填寫付款方式
-
- 資料有加密%s 會加密您儲存的所有付款方式資料在不同裝置間同步卡片資料同步信用卡資訊
-
- 新增信用卡新增付款卡片
-
- 管理已儲存的卡片管理卡片新增地址管理已存地址
-
- 儲存並自動填寫地址儲存並自動填寫地址
-
- 包含電話號碼、E-Mail、收件地址等資訊包含電話號碼與電子郵件地址
@@ -1983,8 +1966,6 @@
刪除卡片
- 你確定要刪除這張信用卡嗎?
-
要刪除卡片嗎?刪除
@@ -1998,24 +1979,15 @@
已儲存的卡片
-
- 請輸入有效的信用卡號
-
請輸入有效卡號
-
- 請填寫此欄位請輸入持卡人姓名解鎖後即可檢視儲存的卡片資訊
- 保護您的信用卡資訊
-
保護您儲存的付款方式
- 設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存的信用卡資訊,避免別人盜用。
-
設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存的付款方式資訊,避免別人盜用。立即設定
@@ -2024,9 +1996,6 @@
裝置解鎖
-
- 解鎖後,即可使用儲存的信用卡資訊
-
解鎖後即可使用儲存的付款方式
@@ -2035,12 +2004,6 @@
編輯地址管理已存地址
-
- 名字
-
- 中間名
-
- 姓氏姓名
@@ -2066,8 +2029,6 @@
刪除地址
-
- 您確定要刪除這筆地址嗎?要刪除這個地址嗎?
@@ -2166,49 +2127,29 @@
刪除編輯
-
- 您確定要刪除這筆登入資訊嗎?你確定要刪除這筆密碼嗎?刪除取消
-
- 登入選項密碼選項
-
- 登入資訊當中,網址的輸入欄位。網址的輸入欄位。
-
- 登入資訊當中,使用者名稱的輸入欄位。使用者名稱的輸入欄位。
- 登入資訊當中,密碼的輸入欄位。
-
密碼的輸入欄位。
-
- 儲存編輯過的登入資訊。儲存變更。
-
- 編輯編輯密碼
-
- 新增登入資訊新增密碼
-
- 需要密碼輸入密碼
- 必須輸入使用者名稱
-
輸入使用者名稱必須輸入主機名稱
@@ -2424,7 +2365,7 @@
感謝您回報!
- 我們將在 24 小時內提供更新過的評論分析資訊,請稍候再回來。
+ 我們將在 24 小時內提供更新過的評論分析資訊,請稍後再回來。我們無法檢查這些評論
@@ -2614,6 +2555,9 @@
關閉翻譯表單
+
+ 暫時無法使用某些設定。
+
翻譯
@@ -2636,6 +2580,9 @@
請選擇一種語言,來管理該語言的「總是翻譯」與「永不翻譯」偏好設定。
+
+ 無法載入語言,請稍後再回來。
+
提供翻譯(預設)
@@ -2659,6 +2606,8 @@
移除 %1$s
+
+ 無法載入網站清單,請稍後再回來。要刪除 %1$s 嗎?
@@ -2736,13 +2685,18 @@
瀏覽上一頁
+
+ 開啟除錯抽屜
+
分頁工具分頁數量
- 使用中
+ 使用中
+
+ 使用中未使用
@@ -2753,6 +2707,16 @@
分頁產生工具要產生的分頁數量
+
+ 文字欄位空白
+
+ 僅可輸入正整數
+
+ 僅可輸入大於 0 的數字
+
+ 超過單一操作中可產生的最大分頁數量(%1$s)新增至使用中的分頁
@@ -2769,11 +2733,11 @@
隱私權公告
- 送出
+ 送出
- 關閉
+ 關閉
- 感謝您的意見回饋!
+ 感謝您的意見回饋!非常滿意
@@ -2785,6 +2749,14 @@
非常不滿意
+
+
+ 開啟問卷
+
+ 關閉問卷
+
+ 關閉
+
登入資訊
diff --git a/mobile/android/fenix/app/src/main/res/values/attrs.xml b/mobile/android/fenix/app/src/main/res/values/attrs.xml
index edd57c6d88..fef61285a5 100644
--- a/mobile/android/fenix/app/src/main/res/values/attrs.xml
+++ b/mobile/android/fenix/app/src/main/res/values/attrs.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/mobile/android/fenix/app/src/main/res/values/colors.xml b/mobile/android/fenix/app/src/main/res/values/colors.xml
index 9abba577a2..d5d58df47e 100644
--- a/mobile/android/fenix/app/src/main/res/values/colors.xml
+++ b/mobile/android/fenix/app/src/main/res/values/colors.xml
@@ -27,11 +27,11 @@
@color/photonYellow20
- @color/photonGreen20
+ @color/photonGreen20
- @color/photonRed10
+ @color/photonRed10
- @color/photonBlue50A44
+ @color/photonBlue50A44
@@ -47,11 +47,11 @@
@color/photonYellow60A40
- @color/photonGreen60
+ @color/photonGreen60
- @color/photonRed30
+ @color/photonRed30
- @color/photonBlue50
+ @color/photonBlue50@color/photonDarkGrey90
@@ -77,9 +77,9 @@
@color/photonDarkGrey90A40
- @color/photonRed70
+ @color/photonRed70
- @color/photonRed70
+ @color/photonRed70@color/photonViolet70
@@ -116,10 +116,10 @@
@color/photonBlue30@color/photonInk20
- @color/photonRed70
+ @color/photonRed70
- @color/photonRed70
- @color/photonViolet60
+ @color/photonRed70
+ @color/photonViolet70@color/photonBlue60@color/photonPink60@color/photonGreen60
@@ -150,15 +150,15 @@
@color/photonDarkGrey90A40
- @color/photonRed70
+ @color/photonRed70
- @color/photonInk50
+ @color/photonViolet90
- @color/photonInk50
+ @color/photonViolet90@color/photonInk90@color/photonInk90
@@ -184,7 +184,7 @@
@color/photonViolet60
- @color/photonLightGrey30
+ @color/photonDarkGrey05@color/photonDarkGrey10
@@ -214,9 +214,9 @@
@color/photonLightGrey05A40
- @color/photonRed20
+ @color/photonRed20
- @color/photonRed70
+ @color/photonRed20@color/photonViolet20
@@ -228,7 +228,7 @@
@color/photonLightGrey05
- @color/photonDarkGrey90
+ @color/photonLightGrey05@color/photonLightGrey05
@@ -251,9 +251,9 @@
@color/photonBlue30@color/photonLightGrey05
- @color/photonRed20
+ @color/photonRed20
- @color/photonRed70
+ @color/photonRed20@color/photonViolet20@color/photonBlue20@color/photonPink20
@@ -262,7 +262,7 @@
@color/photonLightGrey05
- @color/photonDarkGrey90
+ @color/photonLightGrey05@color/photonLightGrey05
@@ -272,7 +272,7 @@
- @color/photonDarkGrey05
+ @color/photonInk05@color/photonInk10@color/photonLightGrey30
@@ -283,7 +283,7 @@
@color/photonLightGrey05A40
- @color/photonRed40
+ @color/photonRed20@color/photonViolet80
diff --git a/mobile/android/fenix/app/src/main/res/values/preference_keys.xml b/mobile/android/fenix/app/src/main/res/values/preference_keys.xml
index 8e94d3251f..678602bd9b 100644
--- a/mobile/android/fenix/app/src/main/res/values/preference_keys.xml
+++ b/mobile/android/fenix/app/src/main/res/values/preference_keys.xml
@@ -17,6 +17,7 @@
pref_key_accessibility_force_enable_zoompref_key_advancedpref_key_language
+ pref_key_translationpref_key_data_choicespref_key_delete_browsing_datapref_key_delete_browsing_data_on_quit_preference
@@ -53,6 +54,9 @@
pref_key_override_sync_tokenserverpref_key_override_push_serverpref_key_sync_debug_quit
+ pref_key_sync_debug_network_error
+ pref_key_sync_debug_temporary_auth_error
+ pref_key_sync_debug_permanent_auth_errorpref_key_customizepref_key_private_browsingpref_key_leakcanary
@@ -164,7 +168,7 @@
pref_key_swipe_toolbar_switch_tabspref_key_swipe_toolbar_show_tabspref_key_recent_tabs
- pref_key_recent_bookmarks
+ pref_key_recent_bookmarkspref_key_customization_category_toolbar
diff --git a/mobile/android/fenix/app/src/main/res/values/static_strings.xml b/mobile/android/fenix/app/src/main/res/values/static_strings.xml
index 66ec907040..6ed8c8901c 100644
--- a/mobile/android/fenix/app/src/main/res/values/static_strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values/static_strings.xml
@@ -66,6 +66,12 @@
Stop FirefoxCustom server changes will take effect on the next Firefox run.
+
+ Simulate account network error
+
+ Simulate temporary account auth error
+
+ Simulate permanent account auth errorEnable Tabs Tray to Compose rewrite
diff --git a/mobile/android/fenix/app/src/main/res/values/strings.xml b/mobile/android/fenix/app/src/main/res/values/strings.xml
index a2a5d53866..9cfeb301e5 100644
--- a/mobile/android/fenix/app/src/main/res/values/strings.xml
+++ b/mobile/android/fenix/app/src/main/res/values/strings.xml
@@ -47,11 +47,19 @@
- Recently saved
+ Recently saved
- Show all saved bookmarks
+ Show all saved bookmarks
- Remove
+ Remove
+
+
+
+ Bookmarks
+
+ Show all bookmarks
+
+ Remove%1$s is produced by Mozilla.
@@ -184,6 +192,10 @@
Add-onsExtensions
+
+ Manage extensions
+
+ Discover more extensionsAccount info
@@ -202,18 +214,26 @@
Open in regular tabAdd to Home screen
+
+ Add to Home screen…InstallResyncFind in page
+
+ Find in page…Translate page
+ Save to collection…
+
Save to collectionShare
+
+ Share…Open in %1$s
@@ -249,6 +269,33 @@
New private tabPasswords
+
+ New in %1$s
+
+ Switch to desktop site
+
+ Tools
+
+ Save
+
+ Bookmark this page
+
+ Edit bookmark
+
+ Save as PDF…
+
+ Turn on Reader View
+
+ Turn off Reader View
+
+ Translate page…
+
+ Translated to %1$s
+
+ Print…
@@ -541,6 +588,10 @@
Reconnect to resume syncingLanguage
+
+ Translation
+
+ TranslationsData choices
@@ -641,7 +692,9 @@
Jump back in
- Recent bookmarks
+ Recent bookmarks
+
+ BookmarksRecently visited
@@ -774,6 +827,14 @@
Tab from %s
+
+
+ %1$s tabs closed: %2$d
+
+ View recently closed tabs
+
Exceptions
@@ -2403,6 +2464,8 @@
Not nowShow original
+
+ Original untranslated page loadedDone
@@ -2576,6 +2639,8 @@
Debug ToolsNavigate back
+
+ Open debug drawer
@@ -2583,7 +2648,10 @@
Tab count
- Active
+ Active
+
+ ActiveInactive
@@ -2601,6 +2669,31 @@
Add to private tabs
+
+
+
+ Continue
+
+ Complete this survey
+
+ Privacy Notice
+
+ Submit
+
+ Close
+
+ Thanks for your feedback!
+
+ Very Satisfied
+
+ Satisfied
+
+ Neutral
+
+ Dissatisfied
+
+ Very Dissatisfied
+
Logins
diff --git a/mobile/android/fenix/app/src/main/res/values/styles.xml b/mobile/android/fenix/app/src/main/res/values/styles.xml
index c7a7932b8a..420511a5e2 100644
--- a/mobile/android/fenix/app/src/main/res/values/styles.xml
+++ b/mobile/android/fenix/app/src/main/res/values/styles.xml
@@ -34,9 +34,9 @@
@color/fx_mobile_text_color_accent@color/fx_mobile_text_color_warning
+ tools:ignore="UnusedResources">@color/fx_mobile_text_color_critical
@color/fx_mobile_text_color_warning
+ tools:ignore="UnusedResources">@color/fx_mobile_text_color_critical
@style/SelectPromptHeaderTextStyle@style/SelectPromptHeaderTextStyle@style/SelectPromptHeaderTextStyle
@@ -67,7 +67,7 @@
@color/fx_mobile_text_color_disabled
- @color/fx_mobile_text_color_warning
+ @color/fx_mobile_text_color_critical@color/fx_mobile_text_color_accent
@@ -230,9 +230,9 @@
@style/BottomSheetPrivate@color/fx_mobile_private_text_color_warning
+ tools:ignore="UnusedResources">@color/fx_mobile_private_text_color_critical
@color/fx_mobile_private_text_color_warning
+ tools:ignore="UnusedResources">@color/fx_mobile_private_text_color_critical
@style/SelectPromptHeaderTextStyle@style/SelectPromptHeaderTextStyle@style/SelectPromptHeaderTextStyle
@@ -263,7 +263,7 @@
@color/fx_mobile_private_text_color_disabled
- @color/fx_mobile_private_text_color_warning
+ @color/fx_mobile_private_text_color_critical@color/fx_mobile_private_text_color_accent
@@ -378,8 +378,8 @@