Copione merged onto master
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
commit
a7bf91e814
|
@ -158,6 +158,7 @@ class HistoryTest {
|
|||
}.openHistory {
|
||||
}.openThreeDotMenu {
|
||||
}.clickDelete {
|
||||
verifyDeleteSnackbarText("Deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +175,7 @@ class HistoryTest {
|
|||
clickDeleteHistoryButton()
|
||||
verifyDeleteConfirmationMessage()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Browsing data deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ class HistoryRobot {
|
|||
.click()
|
||||
}
|
||||
|
||||
fun verifyDeleteSnackbarText(text: String) = assertSnackBarText(text)
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: HistoryRobot.() -> Unit): Transition {
|
||||
goBackButton().click()
|
||||
|
@ -152,3 +154,6 @@ private fun assertDeleteConfirmationMessage() =
|
|||
.check(matches(isDisplayed()))
|
||||
|
||||
private fun assertCopySnackBarText() = snackBarText().check(matches(withText("URL copied")))
|
||||
|
||||
private fun assertSnackBarText(text: String) =
|
||||
snackBarText().check(matches(withText(Matchers.containsString(text))))
|
||||
|
|
|
@ -22,21 +22,8 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
hasUserGesture: Boolean,
|
||||
isSameDomain: Boolean
|
||||
): RequestInterceptor.InterceptionResponse? {
|
||||
var result: RequestInterceptor.InterceptionResponse? = null
|
||||
|
||||
// WebChannel-driven authentication does not require a separate redirect interceptor.
|
||||
@Suppress("ConstantConditionIf")
|
||||
if (FeatureFlags.asFeatureWebChannelsDisabled) {
|
||||
result = context.components.services.accountsAuthFeature.interceptor.onLoadRequest(
|
||||
engineSession, uri, hasUserGesture, isSameDomain)
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
result = context.components.services.appLinksInterceptor.onLoadRequest(
|
||||
engineSession, uri, hasUserGesture, isSameDomain)
|
||||
}
|
||||
|
||||
return result
|
||||
return context.components.services.appLinksInterceptor
|
||||
.onLoadRequest(engineSession, uri, hasUserGesture, isSameDomain)
|
||||
}
|
||||
|
||||
override fun onErrorRequest(
|
||||
|
|
|
@ -10,25 +10,6 @@ object FeatureFlags {
|
|||
*/
|
||||
const val pullToRefreshEnabled = false
|
||||
|
||||
/**
|
||||
* Disables FxA Application Services Web Channels feature
|
||||
*/
|
||||
const val asFeatureWebChannelsDisabled = false
|
||||
|
||||
/**
|
||||
* Disables FxA Application Services Sync feature
|
||||
*/
|
||||
const val asFeatureSyncDisabled = false
|
||||
|
||||
/**
|
||||
* Integration of push support provided by `feature-push` component into the Gecko engine.
|
||||
*
|
||||
* Behind nightly flag until all fatal bugs are resolved.
|
||||
*
|
||||
* https://github.com/mozilla-mobile/fenix/issues/9059
|
||||
*/
|
||||
const val webPushIntegration = true
|
||||
|
||||
/**
|
||||
* Enables tip feature
|
||||
*/
|
||||
|
|
|
@ -37,7 +37,6 @@ import mozilla.components.support.rusthttp.RustHttpConfig
|
|||
import mozilla.components.support.rustlog.RustLog
|
||||
import mozilla.components.support.utils.logElapsedTime
|
||||
import mozilla.components.support.webextensions.WebExtensionSupport
|
||||
import org.mozilla.fenix.FeatureFlags.webPushIntegration
|
||||
import org.mozilla.fenix.components.Components
|
||||
import org.mozilla.fenix.components.metrics.MetricServiceType
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
@ -239,10 +238,7 @@ open class FenixApplication : LocaleAwareApplication() {
|
|||
// Install the AutoPush singleton to receive messages.
|
||||
PushProcessor.install(it)
|
||||
|
||||
if (webPushIntegration) {
|
||||
// WebPush integration to observe and deliver push messages to engine.
|
||||
WebPushEngineIntegration(components.core.engine, it).start()
|
||||
}
|
||||
WebPushEngineIntegration(components.core.engine, it).start()
|
||||
|
||||
// Perform a one-time initialization of the account manager if a message is received.
|
||||
PushFxaIntegration(it, lazy { components.backgroundServices.accountManager }).launch()
|
||||
|
|
|
@ -7,13 +7,10 @@ package org.mozilla.fenix.addons
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import kotlinx.android.synthetic.main.fragment_add_on_details.view.*
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -21,108 +18,35 @@ import kotlinx.coroutines.withContext
|
|||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.ui.showInformationDialog
|
||||
import mozilla.components.feature.addons.ui.translatedName
|
||||
import mozilla.components.feature.addons.ui.translatedDescription
|
||||
import mozilla.components.feature.addons.update.DefaultAddonUpdater.UpdateAttemptStorage
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* A fragment to show the details of an add-on.
|
||||
*/
|
||||
class AddonDetailsFragment : Fragment(R.layout.fragment_add_on_details) {
|
||||
private val updateAttemptStorage: UpdateAttemptStorage by lazy {
|
||||
UpdateAttemptStorage(requireContext())
|
||||
}
|
||||
class AddonDetailsFragment : Fragment(R.layout.fragment_add_on_details), AddonDetailsInteractor {
|
||||
|
||||
private val updateAttemptStorage by lazy { UpdateAttemptStorage(requireContext()) }
|
||||
private val args by navArgs<AddonDetailsFragmentArgs>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
bind(args.addon, view)
|
||||
|
||||
showToolbar(title = args.addon.translatedName)
|
||||
AddonDetailsView(view, interactor = this).bind(args.addon)
|
||||
}
|
||||
|
||||
private fun bind(addon: Addon, view: View) {
|
||||
val title = addon.translatedName
|
||||
showToolbar(title)
|
||||
|
||||
bindDetails(addon, view)
|
||||
bindAuthors(addon, view)
|
||||
bindVersion(addon, view)
|
||||
bindLastUpdated(addon, view)
|
||||
bindWebsite(addon, view)
|
||||
bindRating(addon, view)
|
||||
override fun openWebsite(addonSiteUrl: Uri) {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, addonSiteUrl))
|
||||
}
|
||||
|
||||
private fun bindRating(addon: Addon, view: View) {
|
||||
addon.rating?.let {
|
||||
val ratingView = view.rating_view
|
||||
val userCountView = view.users_count
|
||||
|
||||
val ratingContentDescription =
|
||||
getString(R.string.mozac_feature_addons_rating_content_description)
|
||||
ratingView.contentDescription = String.format(ratingContentDescription, it.average)
|
||||
ratingView.rating = it.average
|
||||
|
||||
userCountView.text = getFormattedAmount(it.reviews)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindWebsite(addon: Addon, view: View) {
|
||||
view.home_page_label.setOnClickListener {
|
||||
val intent =
|
||||
Intent(Intent.ACTION_VIEW).setData(Uri.parse(addon.siteUrl))
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindLastUpdated(addon: Addon, view: View) {
|
||||
view.last_updated_text.text = formatDate(addon.updatedAt)
|
||||
}
|
||||
|
||||
private fun bindVersion(addon: Addon, view: View) {
|
||||
view.version_text.text =
|
||||
addon.installedState?.version?.ifEmpty { addon.version } ?: addon.version
|
||||
if (addon.isInstalled()) {
|
||||
view.version_text.setOnLongClickListener {
|
||||
showUpdaterDialog(addon)
|
||||
true
|
||||
override fun showUpdaterDialog(addon: Addon) {
|
||||
viewLifecycleOwner.lifecycleScope.launch(Main) {
|
||||
val updateAttempt = withContext(IO) {
|
||||
updateAttemptStorage.findUpdateAttemptBy(addon.id)
|
||||
}
|
||||
updateAttempt?.showInformationDialog(requireContext())
|
||||
}
|
||||
}
|
||||
|
||||
private fun showUpdaterDialog(addon: Addon) {
|
||||
viewLifecycleOwner.lifecycleScope.launch(IO) {
|
||||
val updateAttempt = updateAttemptStorage.findUpdateAttemptBy(addon.id)
|
||||
updateAttempt?.let {
|
||||
withContext(Main) {
|
||||
it.showInformationDialog(requireContext())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindAuthors(addon: Addon, view: View) {
|
||||
view.author_text.text = addon.authors.joinToString { author ->
|
||||
author.name
|
||||
}.trim()
|
||||
}
|
||||
|
||||
private fun bindDetails(addon: Addon, view: View) {
|
||||
val detailsView = view.details
|
||||
val detailsText = addon.translatedDescription
|
||||
|
||||
val parsedText = detailsText.replace("\n", "<br/>")
|
||||
val text = HtmlCompat.fromHtml(parsedText, HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
|
||||
detailsView.text = text
|
||||
detailsView.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
|
||||
private fun formatDate(text: String): String {
|
||||
val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
|
||||
return DateFormat.getDateInstance().format(formatter.parse(text)!!)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.addons
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.text.HtmlCompat
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.fragment_add_on_details.*
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.ui.translatedDescription
|
||||
import org.mozilla.fenix.R
|
||||
import java.text.DateFormat
|
||||
import java.text.NumberFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
interface AddonDetailsInteractor {
|
||||
|
||||
/**
|
||||
* Open the given addon siteUrl in the browser.
|
||||
*/
|
||||
fun openWebsite(addonSiteUrl: Uri)
|
||||
|
||||
/**
|
||||
* Display the updater dialog.
|
||||
*/
|
||||
fun showUpdaterDialog(addon: Addon)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the details of an add-on.
|
||||
*/
|
||||
class AddonDetailsView(
|
||||
override val containerView: View,
|
||||
private val interactor: AddonDetailsInteractor
|
||||
) : LayoutContainer {
|
||||
|
||||
private val dateParser = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
|
||||
private val dateFormatter = DateFormat.getDateInstance()
|
||||
private val numberFormatter = NumberFormat.getNumberInstance(Locale.getDefault())
|
||||
|
||||
fun bind(addon: Addon) {
|
||||
bindDetails(addon)
|
||||
bindAuthors(addon)
|
||||
bindVersion(addon)
|
||||
bindLastUpdated(addon)
|
||||
bindWebsite(addon)
|
||||
bindRating(addon)
|
||||
}
|
||||
|
||||
private fun bindRating(addon: Addon) {
|
||||
addon.rating?.let { rating ->
|
||||
val resources = containerView.resources
|
||||
val ratingContentDescription =
|
||||
resources.getString(R.string.mozac_feature_addons_rating_content_description)
|
||||
rating_view.contentDescription = String.format(ratingContentDescription, rating.average)
|
||||
rating_view.rating = rating.average
|
||||
|
||||
users_count.text = numberFormatter.format(rating.reviews)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindWebsite(addon: Addon) {
|
||||
home_page_label.setOnClickListener {
|
||||
interactor.openWebsite(addon.siteUrl.toUri())
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindLastUpdated(addon: Addon) {
|
||||
last_updated_text.text = formatDate(addon.updatedAt)
|
||||
}
|
||||
|
||||
private fun bindVersion(addon: Addon) {
|
||||
var version = addon.installedState?.version
|
||||
if (version.isNullOrEmpty()) {
|
||||
version = addon.version
|
||||
}
|
||||
version_text.text = version
|
||||
|
||||
if (addon.isInstalled()) {
|
||||
version_text.setOnLongClickListener {
|
||||
interactor.showUpdaterDialog(addon)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
version_text.setOnLongClickListener(null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindAuthors(addon: Addon) {
|
||||
author_text.text = addon.authors.joinToString { author -> author.name }.trim()
|
||||
}
|
||||
|
||||
private fun bindDetails(addon: Addon) {
|
||||
val detailsText = addon.translatedDescription
|
||||
|
||||
val parsedText = detailsText.replace("\n", "<br/>")
|
||||
val text = HtmlCompat.fromHtml(parsedText, HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
|
||||
details.text = text
|
||||
details.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
|
||||
private fun formatDate(text: String): String {
|
||||
return dateFormatter.format(dateParser.parse(text)!!)
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import androidx.core.content.res.ResourcesCompat
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.android.synthetic.main.fragment_add_ons_management.*
|
||||
import kotlinx.android.synthetic.main.fragment_add_ons_management.view.*
|
||||
|
@ -23,10 +23,10 @@ import kotlinx.coroutines.Dispatchers.IO
|
|||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.AddonManagerException
|
||||
import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment
|
||||
import mozilla.components.feature.addons.ui.AddonsManagerAdapter
|
||||
import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate
|
||||
import mozilla.components.feature.addons.ui.PermissionsDialogFragment
|
||||
import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment
|
||||
import mozilla.components.feature.addons.ui.translatedName
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.components
|
||||
|
@ -140,7 +140,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management),
|
|||
AddonsManagementFragmentDirections.actionAddonsManagementFragmentToInstalledAddonDetails(
|
||||
addon
|
||||
)
|
||||
Navigation.findNavController(requireView()).navigate(directions)
|
||||
findNavController().navigate(directions)
|
||||
}
|
||||
|
||||
private fun showDetailsFragment(addon: Addon) {
|
||||
|
@ -148,7 +148,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management),
|
|||
AddonsManagementFragmentDirections.actionAddonsManagementFragmentToAddonDetailsFragment(
|
||||
addon
|
||||
)
|
||||
Navigation.findNavController(requireView()).navigate(directions)
|
||||
findNavController().navigate(directions)
|
||||
}
|
||||
|
||||
private fun showNotYetSupportedAddonFragment(unsupportedAddons: ArrayList<Addon>) {
|
||||
|
@ -156,7 +156,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management),
|
|||
AddonsManagementFragmentDirections.actionAddonsManagementFragmentToNotYetSupportedAddonFragment(
|
||||
unsupportedAddons.toTypedArray()
|
||||
)
|
||||
Navigation.findNavController(requireView()).navigate(directions)
|
||||
findNavController().navigate(directions)
|
||||
}
|
||||
|
||||
private fun findPreviousDialogFragment(): PermissionsDialogFragment? {
|
||||
|
|
|
@ -7,17 +7,6 @@ package org.mozilla.fenix.addons
|
|||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import java.text.NumberFormat
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Get the formatted number amount for the current default locale.
|
||||
*
|
||||
* @param amount The number of addons to be formatted for the current default locale..
|
||||
*/
|
||||
internal fun getFormattedAmount(amount: Int): String {
|
||||
return NumberFormat.getNumberInstance(Locale.getDefault()).format(amount)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the Fenix Snackbar in the given view along with the provided text.
|
||||
|
|
|
@ -560,22 +560,19 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
|||
view.swipeRefresh.setOnChildScrollUpCallback { _, _ -> true }
|
||||
}
|
||||
|
||||
@Suppress("ConstantConditionIf")
|
||||
if (!FeatureFlags.asFeatureWebChannelsDisabled) {
|
||||
webchannelIntegration.set(
|
||||
feature = FxaWebChannelFeature(
|
||||
requireContext(),
|
||||
customTabSessionId,
|
||||
requireComponents.core.engine,
|
||||
requireComponents.core.store,
|
||||
requireComponents.backgroundServices.accountManager,
|
||||
requireComponents.backgroundServices.serverConfig,
|
||||
setOf(FxaCapability.CHOOSE_WHAT_TO_SYNC)
|
||||
),
|
||||
owner = this,
|
||||
view = view
|
||||
)
|
||||
}
|
||||
webchannelIntegration.set(
|
||||
feature = FxaWebChannelFeature(
|
||||
requireContext(),
|
||||
customTabSessionId,
|
||||
requireComponents.core.engine,
|
||||
requireComponents.core.store,
|
||||
requireComponents.backgroundServices.accountManager,
|
||||
requireComponents.backgroundServices.serverConfig,
|
||||
setOf(FxaCapability.CHOOSE_WHAT_TO_SYNC)
|
||||
),
|
||||
owner = this,
|
||||
view = view
|
||||
)
|
||||
|
||||
initializeEngineView(toolbarHeight)
|
||||
}
|
||||
|
|
|
@ -81,23 +81,14 @@ class BackgroundServices(
|
|||
// Enabling this for all channels is tracked in https://github.com/mozilla-mobile/fenix/issues/6704
|
||||
secureStateAtRest = Config.channel.isNightlyOrDebug
|
||||
)
|
||||
// If sync has been turned off on the server then disable syncing.
|
||||
@Suppress("ConstantConditionIf")
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
val syncConfig = if (FeatureFlags.asFeatureSyncDisabled) {
|
||||
null
|
||||
|
||||
@VisibleForTesting
|
||||
val supportedEngines = if (FeatureFlags.syncedTabs) {
|
||||
setOf(SyncEngine.History, SyncEngine.Bookmarks, SyncEngine.Passwords, SyncEngine.Tabs)
|
||||
} else {
|
||||
|
||||
val supportedEngines = if (FeatureFlags.syncedTabs) {
|
||||
setOf(SyncEngine.History, SyncEngine.Bookmarks, SyncEngine.Passwords, SyncEngine.Tabs)
|
||||
} else {
|
||||
setOf(SyncEngine.History, SyncEngine.Bookmarks, SyncEngine.Passwords)
|
||||
}
|
||||
|
||||
SyncConfig(
|
||||
supportedEngines,
|
||||
syncPeriodInMinutes = 240L) // four hours
|
||||
setOf(SyncEngine.History, SyncEngine.Bookmarks, SyncEngine.Passwords)
|
||||
}
|
||||
private val syncConfig = SyncConfig(supportedEngines, syncPeriodInMinutes = 240L) // four hours
|
||||
|
||||
init {
|
||||
/* Make the "history", "bookmark", "passwords", and "tabs" stores accessible to workers
|
||||
|
|
|
@ -6,7 +6,6 @@ package org.mozilla.fenix.components
|
|||
import android.content.Context
|
||||
import mozilla.components.service.fxa.ServerConfig
|
||||
import mozilla.components.service.fxa.ServerConfig.Server
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
||||
/**
|
||||
|
@ -14,22 +13,15 @@ import org.mozilla.fenix.ext.settings
|
|||
*/
|
||||
|
||||
object FxaServer {
|
||||
const val CLIENT_ID = "a2270f727f45f648"
|
||||
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
|
||||
|
||||
@Suppress("ConstantConditionIf", "UNUSED_PARAMETER")
|
||||
fun redirectUrl(context: Context) = if (FeatureFlags.asFeatureWebChannelsDisabled) {
|
||||
REDIRECT_URL
|
||||
} else {
|
||||
"urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"
|
||||
}
|
||||
private const val CLIENT_ID = "a2270f727f45f648"
|
||||
const val REDIRECT_URL = "urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"
|
||||
|
||||
fun config(context: Context): ServerConfig {
|
||||
val serverOverride = context.settings().overrideFxAServer
|
||||
val tokenServerOverride = context.settings().overrideSyncTokenServer.ifEmpty { null }
|
||||
if (serverOverride.isEmpty()) {
|
||||
return ServerConfig(Server.RELEASE, CLIENT_ID, redirectUrl(context), tokenServerOverride)
|
||||
return ServerConfig(Server.RELEASE, CLIENT_ID, REDIRECT_URL, tokenServerOverride)
|
||||
}
|
||||
return ServerConfig(serverOverride, CLIENT_ID, redirectUrl(context), tokenServerOverride)
|
||||
return ServerConfig(serverOverride, CLIENT_ID, REDIRECT_URL, tokenServerOverride)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class Services(
|
|||
private val accountManager: FxaAccountManager
|
||||
) {
|
||||
val accountsAuthFeature by lazy {
|
||||
FirefoxAccountsAuthFeature(accountManager, FxaServer.redirectUrl(context)) { context, authUrl ->
|
||||
FirefoxAccountsAuthFeature(accountManager, FxaServer.REDIRECT_URL) { context, authUrl ->
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
val intent = SupportUtils.createAuthCustomTabIntent(context, authUrl)
|
||||
context.startActivity(intent)
|
||||
|
|
|
@ -35,7 +35,7 @@ interface BookmarkController {
|
|||
fun handleBookmarkSharing(item: BookmarkNode)
|
||||
fun handleOpeningBookmark(item: BookmarkNode, mode: BrowsingMode)
|
||||
fun handleBookmarkDeletion(nodes: Set<BookmarkNode>, eventType: Event)
|
||||
fun handleBookmarkFolderDeletion(node: BookmarkNode)
|
||||
fun handleBookmarkFolderDeletion(nodes: Set<BookmarkNode>)
|
||||
fun handleBackPressed()
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class DefaultBookmarkController(
|
|||
private val navController: NavController,
|
||||
private val showSnackbar: (String) -> Unit,
|
||||
private val deleteBookmarkNodes: (Set<BookmarkNode>, Event) -> Unit,
|
||||
private val deleteBookmarkFolder: (BookmarkNode) -> Unit,
|
||||
private val deleteBookmarkFolder: (Set<BookmarkNode>) -> Unit,
|
||||
private val invokePendingDeletion: () -> Unit
|
||||
) : BookmarkController {
|
||||
|
||||
|
@ -94,8 +94,8 @@ class DefaultBookmarkController(
|
|||
deleteBookmarkNodes(nodes, eventType)
|
||||
}
|
||||
|
||||
override fun handleBookmarkFolderDeletion(node: BookmarkNode) {
|
||||
deleteBookmarkFolder(node)
|
||||
override fun handleBookmarkFolderDeletion(nodes: Set<BookmarkNode>) {
|
||||
deleteBookmarkFolder(nodes)
|
||||
}
|
||||
|
||||
override fun handleBackPressed() {
|
||||
|
|
|
@ -274,13 +274,17 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
|||
}
|
||||
|
||||
private fun deleteMulti(selected: Set<BookmarkNode>, eventType: Event = Event.RemoveBookmarks) {
|
||||
selected.forEach { if (it.type == BookmarkNodeType.FOLDER) {
|
||||
showRemoveFolderDialog(selected)
|
||||
return
|
||||
} }
|
||||
updatePendingBookmarksToDelete(selected)
|
||||
|
||||
pendingBookmarkDeletionJob = getDeleteOperation(eventType)
|
||||
|
||||
val message = when (eventType) {
|
||||
is Event.RemoveBookmarks -> {
|
||||
getRemoveBookmarksSnackBarMessage(selected)
|
||||
getRemoveBookmarksSnackBarMessage(selected, containsFolders = false)
|
||||
}
|
||||
is Event.RemoveBookmarkFolder,
|
||||
is Event.RemoveBookmark -> {
|
||||
|
@ -301,9 +305,16 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
|||
)
|
||||
}
|
||||
|
||||
private fun getRemoveBookmarksSnackBarMessage(selected: Set<BookmarkNode>): String {
|
||||
private fun getRemoveBookmarksSnackBarMessage(
|
||||
selected: Set<BookmarkNode>,
|
||||
containsFolders: Boolean
|
||||
): String {
|
||||
return if (selected.size > 1) {
|
||||
getString(R.string.bookmark_deletion_multiple_snackbar_message_2)
|
||||
return if (containsFolders) {
|
||||
getString(R.string.bookmark_deletion_multiple_snackbar_message_3)
|
||||
} else {
|
||||
getString(R.string.bookmark_deletion_multiple_snackbar_message_2)
|
||||
}
|
||||
} else {
|
||||
val bookmarkNode = selected.first()
|
||||
getString(
|
||||
|
@ -314,29 +325,38 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
|||
}
|
||||
}
|
||||
|
||||
private fun getDialogConfirmationMessage(selected: Set<BookmarkNode>): String {
|
||||
return if (selected.size > 1) {
|
||||
getString(R.string.bookmark_delete_multiple_folders_confirmation_dialog, getString(R.string.app_name))
|
||||
} else {
|
||||
getString(R.string.bookmark_delete_folder_confirmation_dialog)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_bookmarkInteractor = null
|
||||
}
|
||||
|
||||
private fun showRemoveFolderDialog(selected: BookmarkNode) {
|
||||
private fun showRemoveFolderDialog(selected: Set<BookmarkNode>) {
|
||||
activity?.let { activity ->
|
||||
AlertDialog.Builder(activity).apply {
|
||||
setMessage(R.string.bookmark_delete_folder_confirmation_dialog)
|
||||
val dialogConfirmationMessage = getDialogConfirmationMessage(selected)
|
||||
setMessage(dialogConfirmationMessage)
|
||||
setNegativeButton(R.string.delete_browsing_data_prompt_cancel) { dialog: DialogInterface, _ ->
|
||||
dialog.cancel()
|
||||
}
|
||||
setPositiveButton(R.string.delete_browsing_data_prompt_allow) { dialog: DialogInterface, _ ->
|
||||
updatePendingBookmarksToDelete(setOf(selected))
|
||||
updatePendingBookmarksToDelete(selected)
|
||||
pendingBookmarkDeletionJob = getDeleteOperation(Event.RemoveBookmarkFolder)
|
||||
dialog.dismiss()
|
||||
val message = getDeleteDialogString(selected)
|
||||
val snackbarMessage = getRemoveBookmarksSnackBarMessage(selected, containsFolders = true)
|
||||
viewLifecycleOwner.lifecycleScope.allowUndo(
|
||||
requireView(),
|
||||
message,
|
||||
snackbarMessage,
|
||||
getString(R.string.bookmark_undo_deletion),
|
||||
{
|
||||
undoPendingDeletion(setOf(selected))
|
||||
undoPendingDeletion(selected)
|
||||
},
|
||||
operation = getDeleteOperation(Event.RemoveBookmarkFolder)
|
||||
)
|
||||
|
@ -353,14 +373,6 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
|||
bookmarkInteractor.onBookmarksChanged(bookmarkTree)
|
||||
}
|
||||
|
||||
private fun getDeleteDialogString(selected: BookmarkNode): String {
|
||||
return getString(
|
||||
R.string.bookmark_deletion_snackbar_message,
|
||||
context?.components?.publicSuffixList?.let { selected.url?.toShortUrl(it) }
|
||||
?: selected.title
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun undoPendingDeletion(selected: Set<BookmarkNode>) {
|
||||
pendingBookmarksToDelete.removeAll(selected)
|
||||
pendingBookmarkDeletionJob = null
|
||||
|
|
|
@ -90,7 +90,7 @@ class BookmarkFragmentInteractor(
|
|||
null -> Event.RemoveBookmarks
|
||||
}
|
||||
if (eventType == Event.RemoveBookmarkFolder) {
|
||||
bookmarksController.handleBookmarkFolderDeletion(nodes.first())
|
||||
bookmarksController.handleBookmarkFolderDeletion(nodes)
|
||||
} else {
|
||||
bookmarksController.handleBookmarkDeletion(nodes, eventType)
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ class HistoryAdapter(
|
|||
|
||||
private var mode: HistoryFragmentState.Mode = HistoryFragmentState.Mode.Normal
|
||||
override val selectedItems get() = mode.selectedItems
|
||||
var pendingDeletionIds = emptySet<Long>()
|
||||
private val itemsWithHeaders: MutableMap<HistoryItemTimeGroup, Int> = mutableMapOf()
|
||||
|
||||
override fun getItemViewType(position: Int): Int = HistoryListItemViewHolder.LAYOUT_ID
|
||||
|
||||
|
@ -48,13 +50,33 @@ class HistoryAdapter(
|
|||
}
|
||||
|
||||
override fun onBindViewHolder(holder: HistoryListItemViewHolder, position: Int) {
|
||||
val previous = if (position == 0) null else getItem(position - 1)
|
||||
val current = getItem(position) ?: return
|
||||
val headerForCurrentItem = timeGroupForHistoryItem(current)
|
||||
val isPendingDeletion = pendingDeletionIds.contains(current.visitedAt)
|
||||
var timeGroup: HistoryItemTimeGroup? = null
|
||||
|
||||
val previousHeader = previous?.let(::timeGroupForHistoryItem)
|
||||
val currentHeader = timeGroupForHistoryItem(current)
|
||||
val timeGroup = if (currentHeader != previousHeader) currentHeader else null
|
||||
holder.bind(current, timeGroup, position == 0, mode)
|
||||
// Add or remove the header and position to the map depending on it's deletion status
|
||||
if (itemsWithHeaders.containsKey(headerForCurrentItem)) {
|
||||
if (isPendingDeletion && itemsWithHeaders[headerForCurrentItem] == position) {
|
||||
itemsWithHeaders.remove(headerForCurrentItem)
|
||||
} else if (isPendingDeletion && itemsWithHeaders[headerForCurrentItem] != position) {
|
||||
// do nothing
|
||||
} else {
|
||||
if (position <= itemsWithHeaders[headerForCurrentItem] as Int) {
|
||||
itemsWithHeaders[headerForCurrentItem] = position
|
||||
timeGroup = headerForCurrentItem
|
||||
}
|
||||
}
|
||||
} else if (!isPendingDeletion) {
|
||||
itemsWithHeaders[headerForCurrentItem] = position
|
||||
timeGroup = headerForCurrentItem
|
||||
}
|
||||
|
||||
holder.bind(current, timeGroup, position == 0, mode, isPendingDeletion)
|
||||
}
|
||||
|
||||
fun updatePendingDeletionIds(pendingDeletionIds: Set<Long>) {
|
||||
this.pendingDeletionIds = pendingDeletionIds
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -17,8 +17,11 @@ import android.view.ViewGroup
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavDirections
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import kotlinx.android.synthetic.main.fragment_history.view.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -31,17 +34,18 @@ import org.mozilla.fenix.HomeActivity
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.addons.showSnackBar
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.mozilla.fenix.components.Components
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.components.StoreProvider
|
||||
import org.mozilla.fenix.components.history.createSynchronousPagedHistoryProvider
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getStringWithArgSafe
|
||||
import org.mozilla.fenix.ext.nav
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.ext.toShortUrl
|
||||
import org.mozilla.fenix.library.LibraryPageFragment
|
||||
import org.mozilla.fenix.utils.allowUndo
|
||||
|
||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||
class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandler {
|
||||
|
@ -49,6 +53,8 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
private lateinit var historyView: HistoryView
|
||||
private lateinit var historyInteractor: HistoryInteractor
|
||||
private lateinit var viewModel: HistoryViewModel
|
||||
private var undoScope: CoroutineScope? = null
|
||||
private var pendingHistoryDeletionJob: (suspend () -> Unit)? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -59,7 +65,10 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
historyStore = StoreProvider.get(this) {
|
||||
HistoryFragmentStore(
|
||||
HistoryFragmentState(
|
||||
items = listOf(), mode = HistoryFragmentState.Mode.Normal
|
||||
items = listOf(),
|
||||
mode = HistoryFragmentState.Mode.Normal,
|
||||
pendingDeletionIds = emptySet(),
|
||||
isDeletingItems = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -111,18 +120,18 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
}
|
||||
|
||||
private fun deleteHistoryItems(items: Set<HistoryItem>) {
|
||||
val message = getMultiSelectSnackBarMessage(items)
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
context?.components?.run {
|
||||
for (item in items) {
|
||||
analytics.metrics.track(Event.HistoryItemRemoved)
|
||||
core.historyStorage.deleteVisit(item.url, item.visitedAt)
|
||||
}
|
||||
}
|
||||
viewModel.invalidate()
|
||||
showSnackBar(requireView(), message)
|
||||
historyStore.dispatch(HistoryFragmentAction.ExitDeletionMode)
|
||||
}
|
||||
|
||||
updatePendingHistoryToDelete(items)
|
||||
undoScope = CoroutineScope(IO)
|
||||
undoScope?.allowUndo(
|
||||
requireView(),
|
||||
getMultiSelectSnackBarMessage(items),
|
||||
getString(R.string.bookmark_undo_deletion),
|
||||
{
|
||||
undoPendingDeletion(items)
|
||||
},
|
||||
getDeleteHistoryItemsOperation(items)
|
||||
)
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
|
@ -146,8 +155,8 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
val menuRes = when (historyStore.state.mode) {
|
||||
HistoryFragmentState.Mode.Normal -> R.menu.library_menu
|
||||
is HistoryFragmentState.Mode.Syncing -> R.menu.library_menu
|
||||
is HistoryFragmentState.Mode.Editing -> R.menu.history_select_multi
|
||||
else -> return
|
||||
}
|
||||
|
||||
inflater.inflate(menuRes, menu)
|
||||
|
@ -162,13 +171,8 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
true
|
||||
}
|
||||
R.id.delete_history_multi_select -> {
|
||||
val message = getMultiSelectSnackBarMessage(selectedItems)
|
||||
viewLifecycleOwner.lifecycleScope.launch(Main) {
|
||||
deleteSelectedHistory(historyStore.state.mode.selectedItems, requireComponents)
|
||||
viewModel.invalidate()
|
||||
historyStore.dispatch(HistoryFragmentAction.ExitDeletionMode)
|
||||
showSnackBar(requireView(), message)
|
||||
}
|
||||
deleteHistoryItems(historyStore.state.mode.selectedItems)
|
||||
historyStore.dispatch(HistoryFragmentAction.ExitEditMode)
|
||||
true
|
||||
}
|
||||
R.id.open_history_in_new_tabs_multi_select -> {
|
||||
|
@ -177,10 +181,7 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
selectedItem.url
|
||||
}
|
||||
|
||||
nav(
|
||||
R.id.historyFragment,
|
||||
HistoryFragmentDirections.actionGlobalHome()
|
||||
)
|
||||
navigate(HistoryFragmentDirections.actionGlobalHome())
|
||||
true
|
||||
}
|
||||
R.id.open_history_in_private_tabs_multi_select -> {
|
||||
|
@ -193,10 +194,7 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
browsingModeManager.mode = BrowsingMode.Private
|
||||
supportActionBar?.hide()
|
||||
}
|
||||
nav(
|
||||
R.id.historyFragment,
|
||||
HistoryFragmentDirections.actionGlobalHome()
|
||||
)
|
||||
navigate(HistoryFragmentDirections.actionGlobalHome())
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
|
@ -206,14 +204,22 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
return if (historyItems.size > 1) {
|
||||
getString(R.string.history_delete_multiple_items_snackbar)
|
||||
} else {
|
||||
getString(
|
||||
requireContext().getStringWithArgSafe(
|
||||
R.string.history_delete_single_item_snackbar,
|
||||
historyItems.first().url.toShortUrl(requireComponents.publicSuffixList)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean = historyView.onBackPressed()
|
||||
override fun onPause() {
|
||||
invokePendingDeletion()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
invokePendingDeletion()
|
||||
return historyView.onBackPressed()
|
||||
}
|
||||
|
||||
private fun openItem(item: HistoryItem, mode: BrowsingMode? = null) {
|
||||
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
||||
|
@ -253,23 +259,58 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun deleteSelectedHistory(
|
||||
selected: Set<HistoryItem>,
|
||||
components: Components = requireComponents
|
||||
) {
|
||||
requireComponents.analytics.metrics.track(Event.HistoryItemRemoved)
|
||||
val storage = components.core.historyStorage
|
||||
for (item in selected) {
|
||||
storage.deleteVisit(item.url, item.visitedAt)
|
||||
}
|
||||
}
|
||||
|
||||
private fun share(data: List<ShareData>) {
|
||||
requireComponents.analytics.metrics.track(Event.HistoryItemShared)
|
||||
val directions = HistoryFragmentDirections.actionGlobalShareFragment(
|
||||
data = data.toTypedArray()
|
||||
)
|
||||
nav(R.id.historyFragment, directions)
|
||||
navigate(directions)
|
||||
}
|
||||
|
||||
private fun navigate(directions: NavDirections) {
|
||||
invokePendingDeletion()
|
||||
findNavController().nav(
|
||||
R.id.historyFragment,
|
||||
directions
|
||||
)
|
||||
}
|
||||
|
||||
private fun getDeleteHistoryItemsOperation(items: Set<HistoryItem>): (suspend () -> Unit) {
|
||||
return {
|
||||
CoroutineScope(IO).launch {
|
||||
historyStore.dispatch(HistoryFragmentAction.EnterDeletionMode)
|
||||
context?.components?.run {
|
||||
for (item in items) {
|
||||
analytics.metrics.track(Event.HistoryItemRemoved)
|
||||
core.historyStorage.deleteVisit(item.url, item.visitedAt)
|
||||
}
|
||||
}
|
||||
historyStore.dispatch(HistoryFragmentAction.ExitDeletionMode)
|
||||
pendingHistoryDeletionJob = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePendingHistoryToDelete(items: Set<HistoryItem>) {
|
||||
pendingHistoryDeletionJob = getDeleteHistoryItemsOperation(items)
|
||||
val ids = items.map { item -> item.visitedAt }.toSet()
|
||||
historyStore.dispatch(HistoryFragmentAction.AddPendingDeletionSet(ids))
|
||||
}
|
||||
|
||||
private fun undoPendingDeletion(items: Set<HistoryItem>) {
|
||||
pendingHistoryDeletionJob = null
|
||||
val ids = items.map { item -> item.visitedAt }.toSet()
|
||||
historyStore.dispatch(HistoryFragmentAction.UndoRemovePendingDeletionSet(ids))
|
||||
}
|
||||
|
||||
private fun invokePendingDeletion() {
|
||||
pendingHistoryDeletionJob?.let {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
it.invoke()
|
||||
}.invokeOnCompletion {
|
||||
pendingHistoryDeletionJob = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun syncHistory() {
|
||||
|
|
|
@ -30,6 +30,8 @@ sealed class HistoryFragmentAction : Action {
|
|||
object ExitEditMode : HistoryFragmentAction()
|
||||
data class AddItemForRemoval(val item: HistoryItem) : HistoryFragmentAction()
|
||||
data class RemoveItemForRemoval(val item: HistoryItem) : HistoryFragmentAction()
|
||||
data class AddPendingDeletionSet(val itemIds: Set<Long>) : HistoryFragmentAction()
|
||||
data class UndoRemovePendingDeletionSet(val itemIds: Set<Long>) : HistoryFragmentAction()
|
||||
object EnterDeletionMode : HistoryFragmentAction()
|
||||
object ExitDeletionMode : HistoryFragmentAction()
|
||||
object StartSync : HistoryFragmentAction()
|
||||
|
@ -41,12 +43,16 @@ sealed class HistoryFragmentAction : Action {
|
|||
* @property items List of HistoryItem to display
|
||||
* @property mode Current Mode of History
|
||||
*/
|
||||
data class HistoryFragmentState(val items: List<HistoryItem>, val mode: Mode) : State {
|
||||
data class HistoryFragmentState(
|
||||
val items: List<HistoryItem>,
|
||||
val mode: Mode,
|
||||
val pendingDeletionIds: Set<Long>,
|
||||
val isDeletingItems: Boolean
|
||||
) : State {
|
||||
sealed class Mode {
|
||||
open val selectedItems = emptySet<HistoryItem>()
|
||||
|
||||
object Normal : Mode()
|
||||
object Deleting : Mode()
|
||||
object Syncing : Mode()
|
||||
data class Editing(override val selectedItems: Set<HistoryItem>) : Mode()
|
||||
}
|
||||
|
@ -73,9 +79,17 @@ private fun historyStateReducer(
|
|||
)
|
||||
}
|
||||
is HistoryFragmentAction.ExitEditMode -> state.copy(mode = HistoryFragmentState.Mode.Normal)
|
||||
is HistoryFragmentAction.EnterDeletionMode -> state.copy(mode = HistoryFragmentState.Mode.Deleting)
|
||||
is HistoryFragmentAction.ExitDeletionMode -> state.copy(mode = HistoryFragmentState.Mode.Normal)
|
||||
is HistoryFragmentAction.EnterDeletionMode -> state.copy(isDeletingItems = true)
|
||||
is HistoryFragmentAction.ExitDeletionMode -> state.copy(isDeletingItems = false)
|
||||
is HistoryFragmentAction.StartSync -> state.copy(mode = HistoryFragmentState.Mode.Syncing)
|
||||
is HistoryFragmentAction.FinishSync -> state.copy(mode = HistoryFragmentState.Mode.Normal)
|
||||
is HistoryFragmentAction.AddPendingDeletionSet ->
|
||||
state.copy(
|
||||
pendingDeletionIds = state.pendingDeletionIds + action.itemIds
|
||||
)
|
||||
is HistoryFragmentAction.UndoRemovePendingDeletionSet ->
|
||||
state.copy(
|
||||
pendingDeletionIds = state.pendingDeletionIds - action.itemIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ class HistoryView(
|
|||
val view: View = LayoutInflater.from(container.context)
|
||||
.inflate(R.layout.component_history, container, true)
|
||||
|
||||
private var items: List<HistoryItem> = listOf()
|
||||
var mode: HistoryFragmentState.Mode = HistoryFragmentState.Mode.Normal
|
||||
private set
|
||||
|
||||
|
@ -116,13 +115,16 @@ class HistoryView(
|
|||
fun update(state: HistoryFragmentState) {
|
||||
val oldMode = mode
|
||||
|
||||
view.progress_bar.isVisible = state.mode === HistoryFragmentState.Mode.Deleting
|
||||
view.progress_bar.isVisible = state.isDeletingItems
|
||||
view.swipe_refresh.isRefreshing = state.mode === HistoryFragmentState.Mode.Syncing
|
||||
view.swipe_refresh.isEnabled =
|
||||
state.mode === HistoryFragmentState.Mode.Normal || state.mode === HistoryFragmentState.Mode.Syncing
|
||||
items = state.items
|
||||
mode = state.mode
|
||||
|
||||
historyAdapter.updatePendingDeletionIds(state.pendingDeletionIds)
|
||||
|
||||
updateEmptyState(state.pendingDeletionIds.size != historyAdapter.currentList?.size)
|
||||
|
||||
historyAdapter.updateMode(state.mode)
|
||||
val first = layoutManager.findFirstVisibleItemPosition()
|
||||
val last = layoutManager.findLastVisibleItemPosition() + 1
|
||||
|
|
|
@ -11,13 +11,13 @@ import kotlinx.android.synthetic.main.library_site_item.view.*
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.hideAndDisable
|
||||
import org.mozilla.fenix.ext.showAndEnable
|
||||
import org.mozilla.fenix.utils.Do
|
||||
import org.mozilla.fenix.library.SelectionHolder
|
||||
import org.mozilla.fenix.library.history.HistoryFragmentState
|
||||
import org.mozilla.fenix.library.history.HistoryInteractor
|
||||
import org.mozilla.fenix.library.history.HistoryItem
|
||||
import org.mozilla.fenix.library.history.HistoryItemMenu
|
||||
import org.mozilla.fenix.library.history.HistoryItemTimeGroup
|
||||
import org.mozilla.fenix.utils.Do
|
||||
|
||||
class HistoryListItemViewHolder(
|
||||
view: View,
|
||||
|
@ -44,8 +44,15 @@ class HistoryListItemViewHolder(
|
|||
item: HistoryItem,
|
||||
timeGroup: HistoryItemTimeGroup?,
|
||||
showDeleteButton: Boolean,
|
||||
mode: HistoryFragmentState.Mode
|
||||
mode: HistoryFragmentState.Mode,
|
||||
isPendingDeletion: Boolean = false
|
||||
) {
|
||||
if (isPendingDeletion) {
|
||||
itemView.history_layout.visibility = View.GONE
|
||||
} else {
|
||||
itemView.history_layout.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
itemView.history_layout.titleView.text = item.title
|
||||
itemView.history_layout.urlView.text = item.url
|
||||
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp">
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
|
@ -21,115 +21,137 @@
|
|||
android:id="@+id/details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:textColor="?primaryText"
|
||||
android:textColorLink="?aboutLink"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/author_label"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/details"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:text="@string/mozac_feature_addons_authors" />
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="@string/mozac_feature_addons_authors"
|
||||
app:layout_constraintEnd_toStartOf="@+id/author_text"
|
||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/details" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/author_text"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/details"
|
||||
android:layout_alignParentEnd="true"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_marginTop="20dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/author_label"
|
||||
app:layout_constraintTop_toBottomOf="@+id/details"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<View
|
||||
android:id="@+id/author_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@+id/author_text"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
android:importantForAccessibility="no" />
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintTop_toBottomOf="@id/author_text"
|
||||
tools:layout_editor_absoluteX="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/version_label"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/author_divider"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:text="@string/mozac_feature_addons_version" />
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/mozac_feature_addons_version"
|
||||
app:layout_constraintEnd_toStartOf="@+id/version_text"
|
||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/author_divider"
|
||||
tools:layout_editor_absoluteY="52dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/version_text"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/author_divider"
|
||||
android:layout_alignParentEnd="true"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/version_label"
|
||||
app:layout_constraintTop_toBottomOf="@+id/author_divider"
|
||||
tools:text="1.2.3" />
|
||||
|
||||
<View
|
||||
android:id="@+id/version_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@+id/version_text"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
android:importantForAccessibility="no" />
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintTop_toBottomOf="@+id/version_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_updated_label"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/version_divider"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:text="@string/mozac_feature_addons_last_updated" />
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/mozac_feature_addons_last_updated"
|
||||
app:layout_constraintEnd_toStartOf="@+id/last_updated_text"
|
||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/version_divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_updated_text"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/version_divider"
|
||||
android:layout_alignParentEnd="true"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/last_updated_label"
|
||||
app:layout_constraintTop_toBottomOf="@+id/version_divider"
|
||||
tools:text="Oct 16, 2019" />
|
||||
|
||||
<View
|
||||
android:id="@+id/last_updated_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@+id/last_updated_text"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
android:importantForAccessibility="no" />
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintTop_toBottomOf="@+id/last_updated_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/home_page_label"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/last_updated_divider"
|
||||
style="@style/AboutHeaderContentText"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/mozac_feature_addons_home_page"
|
||||
android:textColor="?aboutLink"
|
||||
android:text="@string/mozac_feature_addons_home_page" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/last_updated_divider" />
|
||||
|
||||
<View
|
||||
android:id="@+id/home_page_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@+id/home_page_label"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
android:importantForAccessibility="no" />
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintTop_toBottomOf="@+id/home_page_label" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/home_page_divider">
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/home_page_divider">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rating_label"
|
||||
|
@ -171,5 +193,5 @@
|
|||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -1134,8 +1134,16 @@
|
|||
<string name="quick_settings_sheet_secure_connection">Ασφαλής σύνδεση</string>
|
||||
<!-- Label that indicates a site is using a insecure connection -->
|
||||
<string name="quick_settings_sheet_insecure_connection">Μη ασφαλής σύνδεση</string>
|
||||
<!-- Confirmation message for a dialog confirming if the user wants to delete all the permissions for all sites-->
|
||||
<string name="confirm_clear_permissions_on_all_sites">Θέλετε σίγουρα να διαγράψετε όλα τα δικαιώματα σε όλες τις ιστοσελίδες;</string>
|
||||
<!-- Confirmation message for a dialog confirming if the user wants to delete all the permissions for a site-->
|
||||
<string name="confirm_clear_permissions_site">Θέλετε σίγουρα να διαγράψετε όλα τα δικαιώματα για αυτή την ιστοσελίδα;</string>
|
||||
<!-- Confirmation message for a dialog confirming if the user wants to set default value a permission for a site-->
|
||||
<string name="confirm_clear_permission_site">Θέλετε σίγουρα να διαγράψετε αυτό το δικαίωμα για αυτή την ιστοσελίδα;</string>
|
||||
<!-- Label for the Pocket default top site -->
|
||||
<string name="pocket_top_articles">Κορυφαία άρθρα</string>
|
||||
<!-- Bookmark deletion confirmation -->
|
||||
<string name="bookmark_deletion_confirmation">Θέλετε σίγουρα να διαγράψετε αυτό το σελιδοδείκτη;</string>
|
||||
<!-- Browser menu button that adds a top site to the home fragment -->
|
||||
<string name="browser_menu_add_to_top_sites">Προσθήκη στις κορυφαίες ιστοσελίδες</string>
|
||||
<!-- text shown before the issuer name to indicate who its verified by, parameter is the name of
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
<string name="content_description_disable_private_browsing_button">Desactivar la navegación privada</string>
|
||||
<!-- Placeholder text shown in the search bar before a user enters text -->
|
||||
<string name="search_hint">Buscar o ingresar dirección</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_open_tabs_header_2">No hay pestañas abiertas</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_open_tabs_description">Tus pestañas abiertas se mostrarán aquí.</string>
|
||||
|
||||
|
@ -293,7 +291,7 @@
|
|||
<!-- Preference for syncing logins -->
|
||||
<string name="preferences_sync_logins">Credenciales</string>
|
||||
<!-- Preference for syncing tabs -->
|
||||
<string name="preferences_sync_tabs">Pestañas</string>
|
||||
<string name="preferences_sync_tabs_2">Pestañas abiertas</string>
|
||||
<!-- Preference for signing out -->
|
||||
<string name="preferences_sign_out">Salir</string>
|
||||
<!-- Preference displays and allows changing current FxA device name -->
|
||||
|
@ -480,7 +478,7 @@
|
|||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Compartir pestañas</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection">Guardar en la colección</string>
|
||||
<string name="tabs_menu_save_to_collection1">Guardar pestañas en la colección</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Menú de pestañas</string>
|
||||
<!-- Tab menu item to share the tab -->
|
||||
|
@ -692,16 +690,10 @@
|
|||
<string name="delete_browsing_data_quit_off">No</string>
|
||||
|
||||
<!-- Collections -->
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="collections_description">Colecciona las cosas que te importan. Para empezar, guarda pestañas abiertas en una nueva colección.</string>
|
||||
<!-- Collections header on home fragment -->
|
||||
<string name="collections_header">Colecciones</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Menú de colecciones</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header">No hay colecciones</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_collections_description">Tus colecciones se mostrarán aquí.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Seleccionar pestañas</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -907,8 +899,9 @@
|
|||
<!-- text for firefox preview moving tip description -->
|
||||
<string name="tip_firefox_preview_moved_description">Firefox Nightly se actualiza todas las noches y tiene funciones experimentales nuevas.
|
||||
No obstante, puede ser menos estable. Baja nuestro navegador beta para una experiencia más estable.</string>
|
||||
<!-- text for firefox preview moving tip button. "Mozilla Firefox Browser" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button">Obtén el navegador Mozilla Firefox</string>
|
||||
|
||||
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button_2">Obtener Firefox para Android Beta</string>
|
||||
|
||||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly se mudó</string>
|
||||
|
@ -1415,6 +1408,9 @@
|
|||
<!-- Voice search prompt description displayed after the user presses the voice search button -->
|
||||
<string name="voice_search_explainer">Habla ahora</string>
|
||||
|
||||
<!-- The error message in edit login view when a duplicate username exists. -->
|
||||
<string name="saved_login_duplicate">Ya existe una credencial con ese nombre de usuario</string>
|
||||
|
||||
<!-- Synced Tabs -->
|
||||
<!-- Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Conectarse con una cuenta de Firefox.</string>
|
||||
|
@ -1424,5 +1420,19 @@
|
|||
<string name="synced_tabs_reauth">Por favor, vuelve a autentificarte.</string>
|
||||
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
|
||||
<string name="synced_tabs_enable_tab_syncing">Por favor, habilita la sincronización de pestañas.</string>
|
||||
<!-- Text displayed when user has no tabs that have been synced -->
|
||||
<string name="synced_tabs_no_tabs">No tienes ninguna pestaña abierta en Firefox en tus otros dispositivos.</string>
|
||||
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
|
||||
<string name="synced_tabs_sign_in_message">Ver una lista de las pestañas de tus otros dispositivos.</string>
|
||||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Conectarse para sincronizar</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">Límite de sitios frecuentes alcanzado</string>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Para añadir un nuevo sitio frecuente, elimina uno. Mantén presionado el sitio y selecciona eliminar.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">Ok, ¡ya caché!</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -15,14 +15,17 @@
|
|||
<string name="content_description_disable_private_browsing_button">Poista yksityinen selaus käytöstä</string>
|
||||
<!-- Placeholder text shown in the search bar before a user enters text -->
|
||||
<string name="search_hint">Hae tai kirjoita osoite</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_open_tabs_header_2">Ei avoimia välilehtiä</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_open_tabs_description">Avoimet välilehdet näytetään tässä.</string>
|
||||
|
||||
<!-- No Private Tabs Message Description -->
|
||||
<string name="no_private_tabs_description">Yksityiset välilehdet näkyvät tässä.</string>
|
||||
|
||||
<!-- Message announced to the user when tab tray is selected with 1 tab -->
|
||||
<string name="open_tab_tray_single">1 avoin välilehti. Napauta vaihtaaksesi.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
|
||||
<string name="open_tab_tray_plural">%1$s avointa välilehteä. Napauta vaihtaaksesi.</string>
|
||||
|
||||
<!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
|
||||
<string name="about_content">%1$s on Mozillan tuote.</string>
|
||||
|
||||
|
@ -299,7 +302,7 @@
|
|||
<!-- Preference for syncing logins -->
|
||||
<string name="preferences_sync_logins">Kirjautumistiedot</string>
|
||||
<!-- Preference for syncing tabs -->
|
||||
<string name="preferences_sync_tabs">Välilehdet</string>
|
||||
<string name="preferences_sync_tabs_2">Avoimet välilehdet</string>
|
||||
<!-- Preference for signing out -->
|
||||
<string name="preferences_sign_out">Kirjaudu ulos</string>
|
||||
<!-- Preference displays and allows changing current FxA device name -->
|
||||
|
@ -472,6 +475,8 @@
|
|||
<string name="tab_tray_menu_open_new_tab">Uusi välilehti</string>
|
||||
<!-- Shortcut action to open the home screen -->
|
||||
<string name="tab_tray_menu_home">Siirry kotiin</string>
|
||||
<!-- Shortcut action to toggle private mode -->
|
||||
<string name="tab_tray_menu_toggle">Vaihda välilehtitilaa</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Removes tab from collection button. Removes the selected tab from collection when pressed -->
|
||||
<string name="remove_tab_from_collection">Poista välilehti kokoelmasta</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab button. Closes the current session when pressed -->
|
||||
|
@ -485,7 +490,7 @@
|
|||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Jaa välilehdet</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection">Tallenna kokoelmaan</string>
|
||||
<string name="tabs_menu_save_to_collection1">Tallenna välilehdet kokoelmaan</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Välilehtivalikko</string>
|
||||
<!-- Tab menu item to share the tab -->
|
||||
|
@ -701,16 +706,14 @@
|
|||
<string name="delete_browsing_data_quit_off">Pois</string>
|
||||
|
||||
<!-- Collections -->
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="collections_description">Kerää merkitykselliset asiat yhteen. Aloita tallentamalla avoimet välilehdet uudeksi kokoelmaksi.</string>
|
||||
<!-- Collections header on home fragment -->
|
||||
<string name="collections_header">Kokoelmat</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Kokoelmavalikko</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header">Ei kokoelmia</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_collections_description">Kokoelmasi näytetään tässä.</string>
|
||||
<string name="no_collections_header1">Kerää yhteen sinulle tärkeät asiat</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Kokoa yhteen samanlaiset haut, sivustot ja välilehdet nopeaa käyttöä varten.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Valitse välilehdet</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -740,6 +743,9 @@
|
|||
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
|
||||
<string name="create_collection_save">Tallenna</string>
|
||||
|
||||
<!-- Snackbar action to view the collection the user just created or updated -->
|
||||
<string name="create_collection_view">Näytä</string>
|
||||
|
||||
<!-- Default name for a new collection in "name new collection" step of the collection creator. %d is a placeholder for the number of collections-->
|
||||
<string name="create_collection_default_name">Kokoelma %d</string>
|
||||
|
||||
|
@ -919,8 +925,9 @@
|
|||
<!-- text for firefox preview moving tip description -->
|
||||
<string name="tip_firefox_preview_moved_description">Firefox Nightly saa päivityksiä joka yö ja se sisältää kokeellisia uusia ominaisuuksia.
|
||||
Se saattaa kuitenkin olla betaversiota epävakaampi. Lataa betavaiheen selain Nightlya vakaamman kokemuksen saamiseksi.</string>
|
||||
<!-- text for firefox preview moving tip button. "Mozilla Firefox Browser" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button">Hanki Mozilla Firefox -selain</string>
|
||||
|
||||
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button_2">Hanki Firefoxin betaversio Androidille</string>
|
||||
|
||||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly on muuttanut</string>
|
||||
|
@ -975,12 +982,19 @@
|
|||
<string name="onboarding_firefox_account_automatic_signin_failed">Sisäänkirjautuminen epäonnistui</string>
|
||||
<!-- text for the tracking protection onboarding card header -->
|
||||
<string name="onboarding_tracking_protection_header_2">Automaattinen yksityisyys</string>
|
||||
<!-- text for the tracking protection card description
|
||||
The first parameter is the name of the app (e.g. Firefox Preview) -->
|
||||
<string name="onboarding_tracking_protection_description_2">Tietosuoja- ja suojausasetukset estävät seuraimia, haittaohjelmia ja sinua seuraavia yrityksiä.</string>
|
||||
<!-- text for tracking protection radio button option for standard level of blocking -->
|
||||
<string name="onboarding_tracking_protection_standard_button_2">Tavallinen (oletus)</string>
|
||||
<!-- text for standard blocking option button description -->
|
||||
<string name="onboarding_tracking_protection_standard_button_description_2">Estää vähemmän seuraimia. Sivut latautuvat normaalisti.</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_button">Tiukka (suositeltu)</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_option">Tiukka</string>
|
||||
<!-- text for strict blocking option button description -->
|
||||
<string name="onboarding_tracking_protection_strict_button_description_2">Estää enemmän seuraimia, mainoksia ja ponnahdusikkunoita. Sivut latautuvat nopeammin, mutta osa toiminnoista ei välttämättä toimi.</string>
|
||||
<!-- text for the toolbar position card header
|
||||
In English this is an idiom for "choose a side as in an argument or fight"
|
||||
but it is ok to make this more literally about "choosing a position in a physical space -->
|
||||
|
@ -1069,10 +1083,14 @@
|
|||
<string name="preference_enhanced_tracking_protection_explanation_learn_more">Lue lisää</string>
|
||||
<!-- Preference for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_default_1">Tavallinen (oletus)</string>
|
||||
<!-- Preference description for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_description_3">Estää vähemmän seuraimia. Sivut latautuvat normaalisti.</string>
|
||||
<!-- Accessibility text for the Standard protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_info_button">Mitä tavallinen seurannan suojaus estää</string>
|
||||
<!-- Preference for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict">Tiukka</string>
|
||||
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_description_2">Estää enemmän seuraimia, mainoksia ja ponnahdusikkunoita. Sivut latautuvat nopeammin, mutta osa toiminnoista ei välttämättä toimi.</string>
|
||||
<!-- Accessibility text for the Strict protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_info_button">Mitä tiukka seurannan suojaus estää</string>
|
||||
<!-- Preference for enhanced tracking protection for the custom protection settings -->
|
||||
|
@ -1127,6 +1145,8 @@
|
|||
<string name="etp_tracking_content_title">Seurantaan tarkoitettu sisältö</string>
|
||||
<!-- Description of tracking content that can be blocked by Enhanced Tracking Protection -->
|
||||
<string name="etp_tracking_content_description">Estää lataamasta ulkopuolisia mainoksia, videoita ja muuta sisältöä, joka sisältää seurantakoodin. Voi vaikuttaa joidenkin verkkosivustojen toimimiseen.</string>
|
||||
<!-- Enhanced Tracking Protection Onboarding Message shown in a dialog above the toolbar. The first parameter is the name of the application (For example: Fenix) -->
|
||||
<string name="etp_onboarding_cfr_message">Aina kun kilven väri on violetti, %s on estänyt seuraimia sivustolla. Napauta saadaksesi lisätietoja.</string>
|
||||
<!-- Enhanced Tracking Protection message that protection is currently on for this site -->
|
||||
<string name="etp_panel_on">Suojaukset ovat PÄÄLLÄ tällä sivustolla</string>
|
||||
<!-- Enhanced Tracking Protection message that protection is currently off for this site -->
|
||||
|
@ -1413,6 +1433,9 @@
|
|||
<!-- Voice search prompt description displayed after the user presses the voice search button -->
|
||||
<string name="voice_search_explainer">Puhu nyt</string>
|
||||
|
||||
<!-- The error message in edit login view when a duplicate username exists. -->
|
||||
<string name="saved_login_duplicate">Kirjautumistieto tällä käyttäjänimellä on jo olemassa</string>
|
||||
|
||||
<!-- Synced Tabs -->
|
||||
<!-- Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Yhdistä Firefox-tilillä.</string>
|
||||
|
@ -1422,5 +1445,19 @@
|
|||
<string name="synced_tabs_reauth">Tunnistaudu uudelleen.</string>
|
||||
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
|
||||
<string name="synced_tabs_enable_tab_syncing">Ota välilehtien synkronointi käyttöön.</string>
|
||||
<!-- Text displayed when user has no tabs that have been synced -->
|
||||
<string name="synced_tabs_no_tabs">Sinulla ei ole muilla laitteilla avoimia välilehtiä Firefoxissa.</string>
|
||||
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
|
||||
<string name="synced_tabs_sign_in_message">Katso välilehtilistaus muilta laitteiltasi.</string>
|
||||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Kirjaudu sisään synkronoidaksesi</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">Ykkössivustojen määrä täynnä</string>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Lisätäksesi uuden ykkössivuston, poista yksi olemassa oleva. Paina pitkään sivustoa ja valitse poista.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">Selvä</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -13,14 +13,18 @@
|
|||
<string name="content_description_disable_private_browsing_button">Priveenavigaasje útskeakelje</string>
|
||||
<!-- Placeholder text shown in the search bar before a user enters text -->
|
||||
<string name="search_hint">Fier sykterm of adres yn</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_open_tabs_header_2">Gjin iepen ljepblêden</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_open_tabs_description">Jo iepene ljepblêden wurde hjir werjûn.</string>
|
||||
|
||||
<!-- No Private Tabs Message Description -->
|
||||
<string name="no_private_tabs_description">Jo priveeljepblêden wurde hjir werjûn.</string>
|
||||
|
||||
<!-- Message announced to the user when tab tray is selected with 1 tab -->
|
||||
<string name="open_tab_tray_single">1 iepen ljepblêd. Tik om tusken ljepblêden te wikseljen.</string>
|
||||
|
||||
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
|
||||
<string name="open_tab_tray_plural">%1$s iepen ljepblêden. Tik om tusken ljepblêden te wikseljen.</string>
|
||||
|
||||
<!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
|
||||
<string name="about_content">%1$s is makke troch Mozilla.</string>
|
||||
|
||||
|
@ -295,7 +299,7 @@
|
|||
<!-- Preference for syncing logins -->
|
||||
<string name="preferences_sync_logins">Oanmeldingen</string>
|
||||
<!-- Preference for syncing tabs -->
|
||||
<string name="preferences_sync_tabs">Ljepblêden</string>
|
||||
<string name="preferences_sync_tabs_2">Iepen ljeplêden</string>
|
||||
<!-- Preference for signing out -->
|
||||
<string name="preferences_sign_out">Ofmelde</string>
|
||||
<!-- Preference displays and allows changing current FxA device name -->
|
||||
|
@ -480,7 +484,7 @@
|
|||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Ljepblêden diele</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection">Yn kolleksje bewarje</string>
|
||||
<string name="tabs_menu_save_to_collection1">Ljepblêden yn kolleksje bewarje</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Ljepblêdmenu</string>
|
||||
<!-- Tab menu item to share the tab -->
|
||||
|
@ -691,16 +695,14 @@
|
|||
<string name="delete_browsing_data_quit_off">Ut</string>
|
||||
|
||||
<!-- Collections -->
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="collections_description">Sammelje de dingen dy\'t wichtich foar jo binne. Bewarje earst iepen ljepblêden yn in nije kolleksje.</string>
|
||||
<!-- Collections header on home fragment -->
|
||||
<string name="collections_header">Kolleksjes</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Kolleksjesmenu</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header">Gjin kolleksjes</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_collections_description">Jo kolleksjes wurde hjir toand.</string>
|
||||
<string name="no_collections_header1">Sammelje de dingen dy\'t wichtich foar jo binne</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Groepearje fergelykbere sykopdrachten, websites en ljepblêden foar flugge tagong letter.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Ljepblêden selektearje</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -908,8 +910,9 @@
|
|||
<!-- text for firefox preview moving tip description -->
|
||||
<string name="tip_firefox_preview_moved_description">Firefox Nightly wurdt elke nacht bywurke en hat eksperimintele nije funksjes.
|
||||
It kin lykwols minder stabyl wêze. Download ús bètabrowser foar in stabiler ûnderfining.</string>
|
||||
<!-- text for firefox preview moving tip button. "Mozilla Firefox Browser" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button">Download Mozilla Firefox Browser</string>
|
||||
|
||||
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button_2">Download Firefox foar Android Beta</string>
|
||||
|
||||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly is ferpleatst</string>
|
||||
|
@ -1414,6 +1417,9 @@
|
|||
<!-- Voice search prompt description displayed after the user presses the voice search button -->
|
||||
<string name="voice_search_explainer">No sprekke</string>
|
||||
|
||||
<!-- The error message in edit login view when a duplicate username exists. -->
|
||||
<string name="saved_login_duplicate">Der bestiet al in oanmelding mei dy brûkersnamme</string>
|
||||
|
||||
<!-- Synced Tabs -->
|
||||
<!-- Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Ferbine mei in Firefox-account.</string>
|
||||
|
@ -1424,4 +1430,19 @@
|
|||
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
|
||||
<string name="synced_tabs_enable_tab_syncing">Skeakelje it syngronisearjen fan ljepblêden yn.</string>
|
||||
|
||||
<!-- Text displayed when user has no tabs that have been synced -->
|
||||
<string name="synced_tabs_no_tabs">Jo hawwe gjin ljepblêden iepene yn Firefox op jo oare apparaten.</string>
|
||||
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
|
||||
<string name="synced_tabs_sign_in_message">Besjoch in list mei ljepblêden fan jo oare apparaten.</string>
|
||||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Oanmelde om te syngronisearjen</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">Limyt foar topwebsites berikke</string>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Smyt in topwebsite fuort om in nije ta te foegjen. Hâld de website yndrukt en selektearje Fuortsmite.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">OK, begrepen</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
<!-- No Private Tabs Message Description -->
|
||||
<string name="no_private_tabs_description">Accaren-ik n tbaḍnit ad d-ttwaseknen dagi.</string>
|
||||
|
||||
<!-- Message announced to the user when tab tray is selected with 1 tab -->
|
||||
<string name="open_tab_tray_single">1 yiccer i yeldin. Sit akken ad tbeddleḍ iccer.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
|
||||
<string name="open_tab_tray_plural">%1$s waccaren yeldin. Sit akken ad tettbeddileḍ gar waccaren.</string>
|
||||
|
||||
<!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
|
||||
<string name="about_content">%1$s d afares n Mozilla.</string>
|
||||
|
||||
|
@ -700,6 +705,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
|
|||
<string name="collections_header">Tigrummiwin</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Umuɣ n tegrumma</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header1">Sdukkel-d akk tiɣawsiwin i yesεan azal ɣur-k/m</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Segrew akk akken inadiyen, ismal d waccaren yemṣadan akken ad yishil unekcum ɣer-sen mbeεd.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Fren iccaren</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -1439,6 +1448,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
|
|||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Kcem akken ad yemtawi</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">Tewwḍeḍ ɣer talast n usmel</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">IH, awi-t-id</string>
|
||||
|
||||
|
|
|
@ -996,7 +996,7 @@
|
|||
<!-- text for the firefox account onboarding card header when we detect you're already signed in to
|
||||
another Firefox browser. (The word `Firefox` should not be translated)
|
||||
The first parameter is the email of the detected user's account -->
|
||||
<string name="onboarding_firefox_account_auto_signin_header_2">이 휴대폰의 다른 Firefox 브라우저에서 %s로 로그인했습니다. 이 계정으로 로그인 하시겠습니까?</string>
|
||||
<string name="onboarding_firefox_account_auto_signin_header_2">이 휴대폰의 다른 Firefox 브라우저에서 %s로 로그인했습니다. 이 계정으로 로그인하시겠습니까?</string>
|
||||
<!-- text for the button to confirm automatic sign-in -->
|
||||
<string name="onboarding_firefox_account_auto_signin_confirm">예, 로그인함</string>
|
||||
<!-- text for the automatic sign-in button while signing in is in process -->
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
<string name="content_description_disable_private_browsing_button">ປຶດນຳໃຊ້ການທ່ອງເວັບແບບສ່ວນຕົວ</string>
|
||||
<!-- Placeholder text shown in the search bar before a user enters text -->
|
||||
<string name="search_hint">ຄົ້ນຫາ ຫລື ປ້ອນທີ່ຢູ່ໃສ່</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_open_tabs_header_2">ບໍ່ມີແທັບທີ່ເປີດຢູ່</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_open_tabs_description">ແທັບທີ່ເປີດຂອງທ່ານຈະຖືກສະແດງຢູ່ບ່ອນນີ້.</string>
|
||||
|
||||
|
@ -268,7 +266,7 @@
|
|||
<!-- Preference for syncing logins -->
|
||||
<string name="preferences_sync_logins">ລັອກອິນ</string>
|
||||
<!-- Preference for syncing tabs -->
|
||||
<string name="preferences_sync_tabs">ແທັບ</string>
|
||||
<string name="preferences_sync_tabs_2">ເປີດແທັບ</string>
|
||||
<!-- Preference for signing out -->
|
||||
<string name="preferences_sign_out">ອອກຈາກລະບົບ</string>
|
||||
<!-- Preference displays and allows changing current FxA device name -->
|
||||
|
@ -280,6 +278,8 @@
|
|||
<!-- Label summary indicating that sync failed. The first parameter is the date stamp showing last time it succeeded -->
|
||||
<string name="sync_failed_summary">ການ sync ລົ້ມເຫລວ. ການ sync ສຳເລັດຄັ້ງສຸດທ້າຍ: %s</string>
|
||||
|
||||
<!-- Label summary showing never synced -->
|
||||
<string name="sync_failed_never_synced_summary">ການ sync ລົ້ມເຫລວ. ການ sync ຄັ້ງສຸດທ້າຍ: ຍັງບໍ່ເຄີຍ sync</string>
|
||||
<!-- Label summary the date we last synced. The first parameter is date stamp showing last time synced -->
|
||||
<string name="sync_last_synced_summary">Sync ຄັ້ງຫລ້າສຸດ: %s</string>
|
||||
<!-- Label summary showing never synced -->
|
||||
|
@ -375,24 +375,35 @@
|
|||
<!-- Preference for using dark theme -->
|
||||
<string name="preference_dark_theme">ເຂັ້ມ</string>
|
||||
|
||||
<!-- Library -->
|
||||
<!-- Option in Library to open Sessions page -->
|
||||
<string name="library_sessions">ເຊດຊັນ</string>
|
||||
<!-- Option in Library to open Screenshots page -->
|
||||
<string name="library_screenshots">ພາບຫນ້າຈໍ</string>
|
||||
<!-- Option in Library to open Downloads page -->
|
||||
<string name="library_downloads">ດາວໂຫລດ</string>
|
||||
<!-- Option in library to open Bookmarks page -->
|
||||
<string name="library_bookmarks">ບຸກມາກ</string>
|
||||
<!-- Option in library to open Desktop Bookmarks root page -->
|
||||
<string name="library_desktop_bookmarks_root">ບຸກມາກເດສກທັອບ</string>
|
||||
<!-- Option in library to open Desktop Bookmarks "menu" page -->
|
||||
<string name="library_desktop_bookmarks_menu">ເມນູບຸກມາກ</string>
|
||||
<!-- Option in library to open Desktop Bookmarks "toolbar" page -->
|
||||
<string name="library_desktop_bookmarks_toolbar">ແຖບເຄື່ອງມືບຸກມາກ</string>
|
||||
<!-- Option in library to open Desktop Bookmarks "unfiled" page -->
|
||||
<string name="library_desktop_bookmarks_unfiled">ບຸກມາກອື່ນໆ</string>
|
||||
<!-- Option in Library to open History page -->
|
||||
<string name="library_history">ປະຫວັດການໃຊ້ງານ</string>
|
||||
<!-- Option in Library to open Synced Tabs page -->
|
||||
<string name="library_synced_tabs">ແທັບ Synced</string>
|
||||
<!-- Option in Library to open Reading List -->
|
||||
<string name="library_reading_list">ລາຍການອ່ານ</string>
|
||||
<!-- Menu Item Label for Search in Library -->
|
||||
<string name="library_search">ຄົ້ນຫາ</string>
|
||||
<!-- Settings Page Title -->
|
||||
<string name="settings_title">ການຕັ້ງຄ່າ</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): "Menu icon for items on a history item" -->
|
||||
<string name="content_description_history_menu">ເມນູລາຍການປະຫວັດການໃຊ້ງານ</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): "Close button for library settings" -->
|
||||
<string name="content_description_close_button">ປິດ</string>
|
||||
|
||||
|
@ -400,13 +411,31 @@
|
|||
<!-- Title for the list of tabs -->
|
||||
<string name="tab_header_label">ເປີດແທັບ</string>
|
||||
<!-- Title for the list of tabs in the current private session -->
|
||||
<string name="tabs_header_private_title">ເຊດຊັນສ່ວນຕົວ</string>
|
||||
<!-- Title for the list of tabs in the current private session -->
|
||||
<string name="tabs_header_private_tabs_title">ແທັບສ່ວນຕົວ</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
|
||||
<string name="add_tab">ເພີ່ມແທັບ</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
|
||||
<string name="add_private_tab">ເພີ່ມແທັບສ່ວນຕົວ</string>
|
||||
<!-- Text for the new tab button to indicate adding a new private tab in the tab -->
|
||||
<string name="tab_drawer_fab_content">ສ່ວນຕົວ</string>
|
||||
<!-- Text shown as the title of the open tab tray -->
|
||||
<string name="tab_tray_title">ເປີດແທັບ</string>
|
||||
<!-- Text shown in the menu for sharing all tabs -->
|
||||
<string name="tab_tray_menu_item_share">ແບ່ງປັນແທັບທັງໝົດ</string>
|
||||
<!-- Text shown in the menu for closing all tabs -->
|
||||
<string name="tab_tray_menu_item_close">ປິດແທັບທັງຫມົດ</string>
|
||||
<!-- Shortcut action to open new tab -->
|
||||
<string name="tab_tray_menu_open_new_tab">ແທັບໃຫມ່</string>
|
||||
<!-- Shortcut action to open the home screen -->
|
||||
<string name="tab_tray_menu_home">ໄປຫນ້າທຳອິດ</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab button. Closes the current session when pressed -->
|
||||
<string name="close_tab">ປິດແທັບ</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab <title> button. First parameter is tab title -->
|
||||
<string name="close_tab_title">ປິດແທັບ %s</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the open tabs menu when pressed -->
|
||||
<string name="open_tabs_menu">ເປີດເມນູແທັບ</string>
|
||||
<!-- Open tabs menu item to close all tabs -->
|
||||
<string name="tabs_menu_close_all_tabs">ປິດແທັບທັງຫມົດ</string>
|
||||
<!-- Open tabs menu item to share all tabs -->
|
||||
|
@ -427,9 +456,57 @@
|
|||
<!-- Text for the menu button to remove a top site -->
|
||||
<string name="remove_top_site">ລຶບ</string>
|
||||
|
||||
<!-- Postfix for private WebApp titles, placeholder is replaced with app name -->
|
||||
<string name="pwa_site_controls_title_private">%1$s (ໂຫມດສ່ວນຕົວ)</string>
|
||||
|
||||
<!-- History -->
|
||||
<!-- Text for the button to clear all history -->
|
||||
<string name="history_delete_all">ລຶບປະຫວັດການໃຊ້ງານ</string>
|
||||
<!-- Text for the dialog to confirm clearing all history -->
|
||||
<string name="history_delete_all_dialog">ທ່ານຫມັ້ນໃຈແລ້ວບໍ່ວ່າທ່ານຕ້ອງການລົບລ້າງປະຫວັດການໃຊ້ງານຂອງທ່ານ?</string>
|
||||
<!-- Text for the snackbar to confirm that multiple browsing history items has been deleted -->
|
||||
<string name="history_delete_multiple_items_snackbar">ລຶບປະຫວັດການໃຊ້ງານແລ້ວ</string>
|
||||
<!-- Text for the snackbar to confirm that a single browsing history item has been deleted. The first parameter is the shortened URL of the deleted history item. -->
|
||||
<string name="history_delete_single_item_snackbar">ລຶບ %1$s ແລ້ວ</string>
|
||||
<!-- Text for positive action to delete history in deleting history dialog -->
|
||||
<string name="history_clear_dialog">ລົບລ້າງ</string>
|
||||
<!-- History overflow menu copy button -->
|
||||
<string name="history_menu_copy_button">ສຳເນົາ</string>
|
||||
<!-- History overflow menu share button -->
|
||||
<string name="history_menu_share_button">ແບ່ງປັນ</string>
|
||||
<!-- History overflow menu open in new tab button -->
|
||||
<string name="history_menu_open_in_new_tab_button">ເປີດໃນແທັບໃຫມ່</string>
|
||||
<!-- History overflow menu open in private tab button -->
|
||||
<string name="history_menu_open_in_private_tab_button">ເປີດໃນແທັບສ່ວນຕົວ</string>
|
||||
<!-- Text for the button to delete a single history item -->
|
||||
<string name="history_delete_item">ລຶບ</string>
|
||||
|
||||
<!-- History multi select title in app bar
|
||||
The first parameter is the number of bookmarks selected -->
|
||||
<string name="history_multi_select_title">ເລືອກ %1$d ແລ້ວ</string>
|
||||
|
||||
<!-- Text for the button to clear selected history items. The first parameter
|
||||
is a digit showing the number of items you have selected -->
|
||||
<string name="history_delete_some">ລຶບໄອເທັມ %1$d</string>
|
||||
<!-- Text for the header that groups the history for last 24 hours -->
|
||||
<string name="history_24_hours">24 ຊົ່ວໂມງທີ່ຜ່ານມາ</string>
|
||||
<!-- Text for the header that groups the history the past 7 days -->
|
||||
<string name="history_7_days">7 ມື້ທີ່ຜ່ານມາ</string>
|
||||
<!-- Text for the header that groups the history the past 30 days -->
|
||||
<string name="history_30_days">30 ມື້ທີ່ຜ່ານມາ</string>
|
||||
<!-- Text for the header that groups the history older than the last month -->
|
||||
<string name="history_older">ເກົ່າກວ່າ</string>
|
||||
<!-- Text shown when no history exists -->
|
||||
<string name="history_empty_message">ບໍ່ມີປະຫວັດການໃຊ້ງານຢູ່ນີ້</string>
|
||||
|
||||
<!-- Crashes -->
|
||||
<!-- Title text displayed on the tab crash page. This first parameter is the name of the application (For example: Fenix) -->
|
||||
<string name="tab_crash_title_2">ຂໍອະໄພ. %1$s ບໍ່ສາມາດໂຫລດໜ້າເວັບນັ້ນໄດ້.</string>
|
||||
<!-- Description text displayed on the tab crash page -->
|
||||
<string name="tab_crash_description">ທ່ານສາມາດພະຍາຍາມກູ້ຄືນ ຫຼື ປິດແຖບຂ້າງລຸ່ມນີ້.</string>
|
||||
<!-- Close tab button text on the tab crash page -->
|
||||
<string name="tab_crash_close">ປິດແທັບ</string>
|
||||
<!-- Restore tab button text on the tab crash page -->
|
||||
<string name="tab_crash_restore">ກູ້ຄືນແທັບ</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<!-- No Private Tabs Message Description -->
|
||||
<string name="no_private_tabs_description">Uw privétabbladen worden hier weergegeven.</string>
|
||||
|
||||
<!-- Message announced to the user when tab tray is selected with 1 tab -->
|
||||
<string name="open_tab_tray_single">1 open tabblad. Tik om tussen tabbladen te wisselen.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
|
||||
<string name="open_tab_tray_plural">%1$s open tabbladen. Tik om tussen tabbladen te wisselen.</string>
|
||||
|
||||
<!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
|
||||
<string name="about_content">%1$s is gemaakt door Mozilla.</string>
|
||||
|
||||
|
@ -484,6 +489,8 @@
|
|||
<string name="tabs_menu_close_all_tabs">Alle tabbladen sluiten</string>
|
||||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Tabbladen delen</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection1">Tabbladen in collectie opslaan</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Tabbladmenu</string>
|
||||
<!-- Tab menu item to share the tab -->
|
||||
|
@ -700,6 +707,10 @@
|
|||
<string name="collections_header">Collecties</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Collectiesmenu</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header1">Verzamel de dingen die belangrijk voor u zijn</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Groepeer vergelijkbare zoekopdrachten, websites en tabbladen voor snelle toegang later.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Tabbladen selecteren</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -1416,6 +1427,9 @@
|
|||
<!-- Voice search prompt description displayed after the user presses the voice search button -->
|
||||
<string name="voice_search_explainer">Nu spreken</string>
|
||||
|
||||
<!-- The error message in edit login view when a duplicate username exists. -->
|
||||
<string name="saved_login_duplicate">Er bestaat al een aanmelding met die gebruikersnaam</string>
|
||||
|
||||
<!-- Synced Tabs -->
|
||||
<!-- Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Verbinden met een Firefox-account.</string>
|
||||
|
@ -1430,6 +1444,14 @@
|
|||
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
|
||||
<string name="synced_tabs_sign_in_message">Bekijk een lijst met tabbladen van uw overige apparaten.</string>
|
||||
|
||||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Aanmelden om te synchroniseren</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">Limiet voor topwebsites bereikt</string>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Verwijder een topwebsite om een nieuwe toe te voegen. Houd de website ingedrukt en selecteer Verwijderen.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">OK, begrepen</string>
|
||||
|
||||
|
|
|
@ -13,11 +13,16 @@
|
|||
<string name="content_description_disable_private_browsing_button">Çaktivizo shfletim privat</string>
|
||||
<!-- Placeholder text shown in the search bar before a user enters text -->
|
||||
<string name="search_hint">Bëni kërkim ose jepni adresë</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_open_tabs_header_2">S’ka skeda të hapura</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_open_tabs_description">Skedat tuaja të hapura do të shfaqen këtu.</string>
|
||||
|
||||
<!-- No Private Tabs Message Description -->
|
||||
<string name="no_private_tabs_description">Skedat tuaja private do të shfaqen këtu.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 1 tab -->
|
||||
<string name="open_tab_tray_single">1 skedë e hapur. Prekeni që të ndërroni skeda.</string>
|
||||
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
|
||||
<string name="open_tab_tray_plural">%1$s skeda të hapura. Prekeni që të ndërroni skeda.</string>
|
||||
|
||||
<!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
|
||||
<string name="about_content">%1$s prodhohet nga Mozilla.</string>
|
||||
|
||||
|
@ -33,7 +38,7 @@
|
|||
<!-- Delete session button to erase your history in a private session -->
|
||||
<string name="private_browsing_delete_session">Fshije sesionin</string>
|
||||
|
||||
<!-- Private mode shortcut "contextual feature recommender" (CFR) -->
|
||||
<!-- Private mode shortcut "contextual feature recommendation" (CFR) -->
|
||||
<!-- Text for the main message -->
|
||||
<string name="cfr_message">Shtoni një shkurtore për të hapur skeda private që prej skenës Kreu juaj.</string>
|
||||
<!-- Text for the positive button -->
|
||||
|
@ -41,6 +46,14 @@
|
|||
<!-- Text for the negative button -->
|
||||
<string name="cfr_neg_button_text">Jo, faleminderit</string>
|
||||
|
||||
<!-- Search widget "contextual feature recommendation" (CFR) -->
|
||||
<!-- Text for the main message. 'Firefox' intentionally hardcoded here.-->
|
||||
<string name="search_widget_cfr_message">Kaloni më shpejt te Firefox-i. Shtoni te skena juaj e Kreut një <em>widget</em>.</string>
|
||||
<!-- Text for the positive button -->
|
||||
<string name="search_widget_cfr_pos_button_text">Shtoni <em>widget</em></string>
|
||||
<!-- Text for the negative button -->
|
||||
<string name="search_widget_cfr_neg_button_text">Jo tani</string>
|
||||
|
||||
<!-- Home screen icons - Long press shortcuts -->
|
||||
<!-- Shortcut action to open new tab -->
|
||||
<string name="home_screen_shortcut_open_new_tab_2">Skedë e re</string>
|
||||
|
@ -83,6 +96,8 @@
|
|||
<string name="browser_menu_add_to_homescreen">Shtoje te skena e Kreut</string>
|
||||
<!-- Browser menu toggle that installs a Progressive Web App shortcut to the site on the device home screen. -->
|
||||
<string name="browser_menu_install_on_homescreen">Instaloje</string>
|
||||
<!-- Menu option on the toolbar that takes you to synced tabs page-->
|
||||
<string name="synced_tabs">Skeda të njëkohësuara</string>
|
||||
<!-- Browser menu button that opens the find in page menu -->
|
||||
<string name="browser_menu_find_in_page">Gjej në faqe</string>
|
||||
<!-- Browser menu button that creates a private tab -->
|
||||
|
@ -91,8 +106,6 @@
|
|||
<string name="browser_menu_new_tab">Skedë e re</string>
|
||||
<!-- Browser menu button that saves the current tab to a collection -->
|
||||
<string name="browser_menu_save_to_collection_2">Ruaje në koleksion</string>
|
||||
<!-- Browser menu button that opens a dialog to report issues with the current site -->
|
||||
<string name="browser_menu_report_issue">Njoftoni problem sajti</string>
|
||||
<!-- Browser menu button that open a share menu to share the current site -->
|
||||
<string name="browser_menu_share">Ndajeni me të tjerët</string>
|
||||
<!-- Share menu title, displayed when a user is sharing their current site -->
|
||||
|
@ -107,8 +120,10 @@
|
|||
<!-- Browser menu text shown in custom tabs to indicate this is a Fenix tab
|
||||
The first parameter is the name of the app defined in app_name (for example: Fenix) -->
|
||||
<string name="browser_menu_powered_by2">Bazuar në %1$s</string>
|
||||
<!-- Browser menu button to put the the current page in reader mode -->
|
||||
<!-- Browser menu button to put the current page in reader mode -->
|
||||
<string name="browser_menu_read">Pamja Lexues</string>
|
||||
<!-- Browser menu button content description to close reader mode and return the user to the regular browser -->
|
||||
<string name="browser_menu_read_close">Mbylle pamjen lexues</string>
|
||||
<!-- Browser menu button to open the current page in an external app -->
|
||||
<string name="browser_menu_open_app_link">Hape në Aplikacion</string>
|
||||
<!-- Browser menu button to configure reader mode appearance e.g. the used font type and size -->
|
||||
|
@ -250,6 +265,8 @@
|
|||
<string name="preferences_show_search_shortcuts">Shfaqni shkurtore kërkimi</string>
|
||||
<!-- Preference title for switch preference to show search suggestions -->
|
||||
<string name="preferences_show_search_suggestions">Shfaq sugjerime kërkimi</string>
|
||||
<!-- Preference title for switch preference to show voice search button -->
|
||||
<string name="preferences_show_voice_search">Shfaq kërkim zanor</string>
|
||||
<!-- Preference title for switch preference to show search suggestions also in private mode -->
|
||||
<string name="preferences_show_search_suggestions_in_private">Shfaqi në sesione private</string>
|
||||
<!-- Preference title for switch preference to show a clipboard suggestion when searching -->
|
||||
|
@ -277,6 +294,8 @@
|
|||
<string name="preferences_sync_bookmarks">Faqerojtës</string>
|
||||
<!-- Preference for syncing logins -->
|
||||
<string name="preferences_sync_logins">Kredenciale Hyrjesh</string>
|
||||
<!-- Preference for syncing tabs -->
|
||||
<string name="preferences_sync_tabs_2">Skeda të hapura</string>
|
||||
<!-- Preference for signing out -->
|
||||
<string name="preferences_sign_out">Dilni</string>
|
||||
<!-- Preference displays and allows changing current FxA device name -->
|
||||
|
@ -368,7 +387,7 @@
|
|||
|
||||
<!-- Pairing Feature strings -->
|
||||
<!-- Instructions on how to access pairing -->
|
||||
<string name="pair_instructions"><![CDATA[Që të merrni kodin tuaj QR, vizitoni <b>firefox.com/pair</b> në Firefox te kompjuteri juaj.]]></string>
|
||||
<string name="pair_instructions_2"><![CDATA[Skanoni kodin QR te <b>firefox.com/pair</b>]]></string>
|
||||
<!-- Button to open camera for pairing -->
|
||||
<string name="pair_open_camera">Hap Kamerën</string>
|
||||
<!-- Button to cancel pairing -->
|
||||
|
@ -409,6 +428,8 @@
|
|||
<string name="library_desktop_bookmarks_unfiled">Faqerojtës të Tjerë</string>
|
||||
<!-- Option in Library to open History page -->
|
||||
<string name="library_history">Historik</string>
|
||||
<!-- Option in Library to open Synced Tabs page -->
|
||||
<string name="library_synced_tabs">Skeda të njëkohësuara</string>
|
||||
<!-- Option in Library to open Reading List -->
|
||||
<string name="library_reading_list">Listë Leximesh</string>
|
||||
<!-- Menu Item Label for Search in Library -->
|
||||
|
@ -429,6 +450,26 @@
|
|||
<string name="tabs_header_private_tabs_title">Skeda private</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
|
||||
<string name="add_tab">Shtoni skedë</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
|
||||
<string name="add_private_tab">Shtoni skedë private</string>
|
||||
<!-- Text for the new tab button to indicate adding a new private tab in the tab -->
|
||||
<string name="tab_drawer_fab_content">Private</string>
|
||||
<!-- Text shown as the title of the open tab tray -->
|
||||
<string name="tab_tray_title">Hapi Skedat</string>
|
||||
<!-- Text shown in the menu for saving tabs to a collection -->
|
||||
<string name="tab_tray_menu_item_save">Ruaje në koleksion</string>
|
||||
<!-- Text shown in the menu for sharing all tabs -->
|
||||
<string name="tab_tray_menu_item_share">Nda krejt skedat</string>
|
||||
<!-- Text shown in the menu for closing all tabs -->
|
||||
<string name="tab_tray_menu_item_close">Mbylli krejt skedat</string>
|
||||
<!-- Shortcut action to open new tab -->
|
||||
<string name="tab_tray_menu_open_new_tab">Skedë e re</string>
|
||||
<!-- Shortcut action to open the home screen -->
|
||||
<string name="tab_tray_menu_home">Shko te kreu</string>
|
||||
<!-- Shortcut action to toggle private mode -->
|
||||
<string name="tab_tray_menu_toggle">Ndërroni mënyrë skedash</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Removes tab from collection button. Removes the selected tab from collection when pressed -->
|
||||
<string name="remove_tab_from_collection">Hiq skedë prej koleksionit</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab button. Closes the current session when pressed -->
|
||||
<string name="close_tab">Mbylle skedën</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Close tab <title> button. First parameter is tab title -->
|
||||
|
@ -439,9 +480,9 @@
|
|||
<string name="tabs_menu_close_all_tabs">Mbylli krejt skedat</string>
|
||||
<!-- Open tabs menu item to share all tabs -->
|
||||
<string name="tabs_menu_share_tabs">Ndani skeda me të tjerët</string>
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection">Ruaje në koleksion</string>
|
||||
|
||||
<!-- Open tabs menu item to save tabs to collection -->
|
||||
<string name="tabs_menu_save_to_collection1">Ruaj skeda në koleksion</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
|
||||
<string name="tab_menu">Menu skedash</string>
|
||||
<!-- Tab menu item to share the tab -->
|
||||
|
@ -653,16 +694,14 @@
|
|||
<string name="delete_browsing_data_quit_off">Off</string>
|
||||
|
||||
<!-- Collections -->
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="collections_description">Koleksiononi gjërat që kanë rëndësi për ju. Për t’ia filluar, ruani skedat e hapura në një koleksion të ri.</string>
|
||||
<!-- Collections header on home fragment -->
|
||||
<string name="collections_header">Koleksione</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Menu koleksionesh</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header">S’ka koleksione</string>
|
||||
<!-- No Open Tabs Message Description -->
|
||||
<string name="no_collections_description">Koleksionet tuaja do të shfaqen këtu.</string>
|
||||
<string name="no_collections_header1">Koleksiononi gjërat që kanë rëndësi për ju</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Gruponi tok kërkime, sajte dhe skeda të ngjashme, për përdorim të shpejtë më pas.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Përzgjidhni Skeda</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
|
@ -692,6 +731,9 @@
|
|||
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
|
||||
<string name="create_collection_save">Ruaje</string>
|
||||
|
||||
<!-- Snackbar action to view the collection the user just created or updated -->
|
||||
<string name="create_collection_view">Shiheni</string>
|
||||
|
||||
<!-- Default name for a new collection in "name new collection" step of the collection creator. %d is a placeholder for the number of collections-->
|
||||
<string name="create_collection_default_name">Koleksioni %d</string>
|
||||
|
||||
|
@ -802,14 +844,14 @@
|
|||
<string name="preference_accessibility_font_size_title">Madhësi Shkronjash</string>
|
||||
|
||||
<!-- Title for Accessibility Text Automatic Size Scaling Preference -->
|
||||
<string name="preference_accessibility_auto_size">Përmasim Automatik i Shkronjave</string>
|
||||
<string name="preference_accessibility_auto_size_2">Përmasim automatik i shkronjave</string>
|
||||
<!-- Summary for Accessibility Text Automatic Size Scaling Preference -->
|
||||
<string name="preference_accessibility_auto_size_summary">Madhësia e shkronjave do të përputhet me rregullimet tuaja në Android. Që të administroni madhësi shkronjash prej këtu, çaktivizojeni.</string>
|
||||
|
||||
<!-- Title for the Delete browsing data preference -->
|
||||
<string name="preferences_delete_browsing_data">Fshi të dhëna shfletimi</string>
|
||||
<!-- Title for the tabs item in Delete browsing data -->
|
||||
<string name="preferences_delete_browsing_data_tabs_title">Skeda të Hapura</string>
|
||||
<string name="preferences_delete_browsing_data_tabs_title_2">Skeda të hapura</string>
|
||||
<!-- Subtitle for the tabs item in Delete browsing data, parameter will be replaced with the number of open tabs -->
|
||||
<string name="preferences_delete_browsing_data_tabs_subtitle">%d skeda</string>
|
||||
|
||||
|
@ -868,8 +910,9 @@
|
|||
<!-- text for firefox preview moving tip description -->
|
||||
<string name="tip_firefox_preview_moved_description">Firefox Nightly përditësohet përnatë dhe ka veçori të reja eksperimentale.
|
||||
Por, është më pak i qëndrueshëm. Për funksionim më të qëndrueshëm, shkarkoni shfletuesin tonë beta.</string>
|
||||
<!-- text for firefox preview moving tip button. "Mozilla Firefox Browser" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button">Merrni Shfletuesin Firefox të Mozilla-s</string>
|
||||
|
||||
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_button_2">Merrni Firefox-in për Android Beta</string>
|
||||
|
||||
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
|
||||
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly është lëvizur</string>
|
||||
|
@ -923,18 +966,20 @@
|
|||
<!-- text to display in the snackbar if automatic sign-in fails. user may try again -->
|
||||
<string name="onboarding_firefox_account_automatic_signin_failed">S’u arrit të hyhej</string>
|
||||
<!-- text for the tracking protection onboarding card header -->
|
||||
<string name="onboarding_tracking_protection_header">Mbroni veten</string>
|
||||
<string name="onboarding_tracking_protection_header_2">Privatësi e vetvetishme</string>
|
||||
<!-- text for the tracking protection card description
|
||||
The first parameter is the name of the app (e.g. Firefox Preview) -->
|
||||
<string name="onboarding_tracking_protection_description1">%s ndihmon të ndalen sajtet nga ndjekja juaj në internet.</string>
|
||||
<string name="onboarding_tracking_protection_description_2">Rregullimet e privatësisë dhe sigurisë bllokojnë gjurmues, malware, dhe shoqëri që ju ndjekin.</string>
|
||||
<!-- text for tracking protection radio button option for standard level of blocking -->
|
||||
<string name="onboarding_tracking_protection_standard_button">Standarde</string>
|
||||
<string name="onboarding_tracking_protection_standard_button_2">Standarde (parazgjedhje)</string>
|
||||
<!-- text for standard blocking option button description -->
|
||||
<string name="onboarding_tracking_protection_standard_button_description">Bllokon më pak gjurmues por lejon që faqet të ngarkohen normalisht</string>
|
||||
<string name="onboarding_tracking_protection_standard_button_description_2">Bllokon më pak gjurmues. Faqet do të ngarkohen normalisht.</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_button">Strikte (e këshilluar)</string>
|
||||
<!-- text for tracking protection radio button option for strict level of blocking -->
|
||||
<string name="onboarding_tracking_protection_strict_option">Strikte</string>
|
||||
<!-- text for strict blocking option button description -->
|
||||
<string name="onboarding_tracking_protection_strict_button_description">Bllokon më shumë gjurmues për mbrojtje dhe punim më të mirë, por mund të bëjë që disa sajte të mos funksionojnë siç duhet</string>
|
||||
<string name="onboarding_tracking_protection_strict_button_description_2">Bllokon më shumë gjurmues, reklama dhe flluska. Faqet ngarkohen më shpejt, por disa anë mund të mos punojnë.</string>
|
||||
<!-- text for the toolbar position card header
|
||||
In English this is an idiom for "choose a side as in an argument or fight"
|
||||
but it is ok to make this more literally about "choosing a position in a physical space -->
|
||||
|
@ -1023,31 +1068,21 @@
|
|||
<!-- Text displayed that links to website about enhanced tracking protection -->
|
||||
<string name="preference_enhanced_tracking_protection_explanation_learn_more">Mësoni më tepër</string>
|
||||
<!-- Preference for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_option">Standarde</string>
|
||||
<!-- Preference for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard">Standarde (e këshilluar)</string>
|
||||
<string name="preference_enhanced_tracking_protection_standard_default_1">Standarde (parazgjedhje)</string>
|
||||
<!-- Preference description for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_description">E baraspeshuar për mbrojtje dhe funksionim.</string>
|
||||
<!-- Preference description for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_description_2">Faqet do të ngarkohen normalisht, por blloko më pak gjurmues.</string>
|
||||
<string name="preference_enhanced_tracking_protection_standard_description_3">Bllokon më pak gjurmues. Faqet do të ngarkohen normalisht.</string>
|
||||
<!-- Accessibility text for the Standard protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_standard_info_button">Ç’bllokohet nga mbrojtje standarde kundër gjurmimit</string>
|
||||
<!-- Preference for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict">Strikte</string>
|
||||
<!-- Preference for enhanced tracking protection for the strict protection settings, default setting -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_default">Strikte (Parazgjedhje)</string>
|
||||
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_default_description">Mbrojtje më e fortë kundër gjurmimit dhe punim më i shpejtë, por disa sajte mund të mos funksionojnë siç duhet.</string>
|
||||
<!-- Preference for enhanced tracking protection for the standard protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_recommended">Strikte (e këshilluar)</string>
|
||||
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_description">Mbrojtje më e fortë, mund të shkaktojë mosfunksionim për disa sajte ose lëndë.</string>
|
||||
<string name="preference_enhanced_tracking_protection_strict_description_2">Bllokon më shumë gjurmues, reklama dhe flluska. Faqet ngarkohen më shpejt, por disa anë mund të mos punojnë.</string>
|
||||
<!-- Accessibility text for the Strict protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_strict_info_button">Ç’bllokohet nga mbrojtje strikte kundër gjurmimit</string>
|
||||
<!-- Preference for enhanced tracking protection for the custom protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_custom">Vetjake</string>
|
||||
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
|
||||
<string name="preference_enhanced_tracking_protection_custom_description">Zgjidhni cilët gjurmues dhe programthe të bllokohen</string>
|
||||
<string name="preference_enhanced_tracking_protection_custom_description_2">Zgjidhni cilët gjurmues dhe programthe të bllokohen.</string>
|
||||
<!-- Accessibility text for the Strict protection information icon -->
|
||||
<string name="preference_enhanced_tracking_protection_custom_info_button">Ç’bllokohet nga mbrojtje vetjake kundër gjurmimit</string>
|
||||
<!-- Header for categories that are being blocked by current Enhanced Tracking Protection settings -->
|
||||
|
@ -1097,7 +1132,7 @@
|
|||
<!-- Description of tracking content that can be blocked by Enhanced Tracking Protection -->
|
||||
<string name="etp_tracking_content_description">Ndal ngarkim reklamash, videosh dhe lënde tjetër të jashtme që përmban kod gjurmimi. Mund të prekë punimin e disa sajteve.</string>
|
||||
<!-- Enhanced Tracking Protection Onboarding Message shown in a dialog above the toolbar. The first parameter is the name of the application (For example: Fenix) -->
|
||||
<string name="etp_onboarding_message_2">Kur mburoja është e purpur, %s bllokon gjurmues në këtë sajt. Prekeni që të shihni se ç’është e bllokuar.</string>
|
||||
<string name="etp_onboarding_cfr_message">Sa herë që mburoja është e purpur, %s ka bllokuar gjurmues në një sajt. Për më tepër të dhëna, prekeni.</string>
|
||||
<!-- Enhanced Tracking Protection message that protection is currently on for this site -->
|
||||
<string name="etp_panel_on">Për këtë sajt, mbrojtjet janë ON</string>
|
||||
<!-- Enhanced Tracking Protection message that protection is currently off for this site -->
|
||||
|
@ -1379,4 +1414,37 @@
|
|||
<string name="edit">Përpunoni</string>
|
||||
<!-- The error message in edit login view when password field is blank. -->
|
||||
<string name="saved_login_password_required">Lypset fjalëkalim</string>
|
||||
|
||||
<!-- Voice search button content description -->
|
||||
<string name="voice_search_content_description">Kërkim zanor</string>
|
||||
<!-- Voice search prompt description displayed after the user presses the voice search button -->
|
||||
<string name="voice_search_explainer">Flisni</string>
|
||||
|
||||
<!-- The error message in edit login view when a duplicate username exists. -->
|
||||
<string name="saved_login_duplicate">Ka tashmë një palë kredenciale me këtë emër përdoruesi</string>
|
||||
|
||||
<!-- Synced Tabs -->
|
||||
<!-- Text displayed when user is not logged into a Firefox Account -->
|
||||
<string name="synced_tabs_connect_to_sync_account">Lidhuni me Llogaritë Firefox.</string>
|
||||
<!-- Text displayed to ask user to connect another device as no devices found with account -->
|
||||
<string name="synced_tabs_connect_another_device">Lidhni pajisje tjetër.</string>
|
||||
<!-- Text displayed asking user to re-authenticate -->
|
||||
<string name="synced_tabs_reauth">Ju lutemi, ribëni mirëfilltësimin.</string>
|
||||
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
|
||||
<string name="synced_tabs_enable_tab_syncing">Ju lutemi, aktivizoni njëkohësim skedash.</string>
|
||||
<!-- Text displayed when user has no tabs that have been synced -->
|
||||
<string name="synced_tabs_no_tabs">S’keni ndonjë skedë të hapur te Firefox-i në pajisje tuajat të tjera.</string>
|
||||
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
|
||||
<string name="synced_tabs_sign_in_message">Shihni një listë skedash nga pajisje tuajat të tjera.</string>
|
||||
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
|
||||
<string name="synced_tabs_sign_in_button">Bëni hyrjen që të sjëkohësoni</string>
|
||||
|
||||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">U mbërrit te kufi sajtesh</string>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Që të shtoni një sajt të ri kryesues, hiqni një të tillë. Mbajeni të shtypur mbi sajtin dhe përzgjidhni Hiqe.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">OK, e mora vesh</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -658,18 +658,113 @@
|
|||
<string name="quick_settings_sheet">Ñanj \'na\' sa ga\'ue nāgi\'iô\' hīo doj</string>
|
||||
<!-- Label that indicates that this option it the recommended one -->
|
||||
<string name="phone_feature_recommended">Sā sà\'a huin ânj</string>
|
||||
<!-- button that allows editing site permissions settings -->
|
||||
<string name="quick_settings_sheet_manage_site_permissions">Gānikāj ñu\'ūnj sa achín nì\'iaj nīkāj sîtio</string>
|
||||
<!-- Button label for clearing all the information of site permissions-->
|
||||
<string name="clear_permissions">Nādure\' nej sa achín nì\'iaj</string>
|
||||
<!-- Button label for clearing a site permission-->
|
||||
<string name="clear_permission">Nādure\' sa achín nì\'iaj</string>
|
||||
<!-- Button label for clearing all the information on all sites-->
|
||||
<string name="clear_permissions_on_all_sites">Nādure\' nej sa achín nì\'iaj riña daran\' nej sîtio</string>
|
||||
<!-- Preference for altering video and audio autoplay for all websites -->
|
||||
<string name="preference_browser_feature_autoplay">Nānùn ma\'an man</string>
|
||||
<!-- Preference for altering the camera access for all websites -->
|
||||
<string name="preference_phone_feature_camera">Kâmara</string>
|
||||
<!-- Preference for altering the microphone access for all websites -->
|
||||
<string name="preference_phone_feature_microphone">Aga\' uxun nanèe</string>
|
||||
<!-- Preference for altering the location access for all websites -->
|
||||
<string name="preference_phone_feature_location">Danè\' huin</string>
|
||||
<!-- Preference for altering the notification access for all websites -->
|
||||
<string name="preference_phone_feature_notification">Sa atāj nan\'ānj an</string>
|
||||
<!-- Label that indicates that a permission must be asked always -->
|
||||
<string name="preference_option_phone_feature_ask_to_allow">Gāchinj nì\'iaj</string>
|
||||
<!-- Label that indicates that a permission must be blocked -->
|
||||
<string name="preference_option_phone_feature_blocked">Nitāj si hūaj nāyi\'nïn</string>
|
||||
<!-- Label that indicates that a permission must be allowed -->
|
||||
<string name="preference_option_phone_feature_allowed">Gā\'ue</string>
|
||||
<!--Label that indicates a permission is by the Android OS-->
|
||||
<string name="phone_feature_blocked_by_android">Nitāj si hūaj nāyi\'nïn \'iaj Android</string>
|
||||
<!-- Preference for showing a list of websites that the default configurations won't apply to them -->
|
||||
<string name="preference_exceptions">Sa huā gi\'iát</string>
|
||||
<!-- Summary of tracking protection preference if tracking protection is set to on -->
|
||||
<string name="tracking_protection_on">Nāchrūn</string>
|
||||
<!-- Summary of tracking protection preference if tracking protection is set to off -->
|
||||
<string name="tracking_protection_off">Dūnâ\’àj</string>
|
||||
<!-- Label that indicates that all video and audio autoplay is allowed -->
|
||||
<string name="preference_option_autoplay_allowed2">Gā\'nïn gī\'iaj sun sa unïnt ngà sa ni\'iājt</string>
|
||||
<!-- Label that indicates that video and audio autoplay is only allowed over Wi-Fi -->
|
||||
<string name="preference_option_autoplay_allowed_wifi_only2">Nārán riña sa unïnt ngà sa ni\'iājt ngà datô si āgâ\'t li</string>
|
||||
<!-- Subtext that explains 'autoplay on Wi-Fi only' option -->
|
||||
<string name="preference_option_autoplay_allowed_wifi_subtext">Nānùn sa unïnt ngà sa ni\'iājt ngà Wi-Fi</string>
|
||||
<!-- Label that indicates that video autoplay is allowed, but audio autoplay is blocked -->
|
||||
<string name="preference_option_autoplay_block_audio2">Màn riña sa unïnt nārán</string>
|
||||
<!-- Label that indicates that all video and audio autoplay is blocked -->
|
||||
<string name="preference_option_autoplay_blocked3">Nārán riña sa unïnt ngà sa ni\'iājt</string>
|
||||
<!-- Summary of delete browsing data on quit preference if it is set to on -->
|
||||
<string name="delete_browsing_data_quit_on">Nāchrūn</string>
|
||||
<!-- Summary of delete browsing data on quit preference if it is set to off -->
|
||||
<string name="delete_browsing_data_quit_off">Dūnâ\’àj</string>
|
||||
|
||||
<!-- Collections -->
|
||||
<!-- Collections header on home fragment -->
|
||||
<string name="collections_header">Koleksiôn</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
|
||||
<string name="collection_menu_button_content_description">Si menû koleksiûn</string>
|
||||
<!-- No Open Tabs Message Header -->
|
||||
<string name="no_collections_header1">Nāran\' daran\' sa ni\'ñānj ruhuât</string>
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
<string name="no_collections_description1">Nāgi\'iaj chrē\' sa nana\'uî\'t, sitio nī nej rakïj ñanj guñā hua da\' ga\'ue gātū hìot ne\' rūkù.</string>
|
||||
<!-- Title for the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_tabs">Nāguī nej rakïj ñanj</string>
|
||||
<!-- Title for the "select collection" step of the collection creator -->
|
||||
<string name="create_collection_select_collection">Nāguī sa màn yì\'nïn\'ïn</string>
|
||||
<!-- Title for the "name collection" step of the collection creator -->
|
||||
<string name="create_collection_name_collection">Si yugui sa màn yì\'nïn\'ïn</string>
|
||||
<!-- Button to add new collection for the "select collection" step of the collection creator -->
|
||||
<string name="create_collection_add_new_collection">Nūtà\' \'ngō yi\'nïn\' nākàa</string>
|
||||
<!-- Button to select all tabs in the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_select_all">Gīda\'a daran\'anj</string>
|
||||
<!-- Button to deselect all tabs in the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_deselect_all">Nā\'nïnj ra\'a daran\'anj</string>
|
||||
<!-- Text to prompt users to select the tabs to save in the "select tabs" step of the collection creator -->
|
||||
<string name="create_collection_save_to_collection_empty">Nāguī nej rakïj ñanj ruhuât nā\'nïnj sà\'t</string>
|
||||
<!-- Text to show users how many tabs they have selected in the "select tabs" step of the collection creator.
|
||||
%d is a placeholder for the number of tabs selected. -->
|
||||
<string name="create_collection_save_to_collection_tabs_selected">%d nej rakïj ñanj naguit</string>
|
||||
<!-- Text to show users they have one tab selected in the "select tabs" step of the collection creator.
|
||||
%d is a placeholder for the number of tabs selected. -->
|
||||
<string name="create_collection_save_to_collection_tab_selected">%d rakïj ñanj naguit</string>
|
||||
<!-- Text shown in snackbar when multiple tabs have been saved in a collection -->
|
||||
<string name="create_collection_tabs_saved">Nej rakïj ñanj na\'nín sà\'t</string>
|
||||
<!-- Text shown in snackbar when one tab has been saved in a collection -->
|
||||
<string name="create_collection_tab_saved">Rakïj ñanj na\'nïnj sà\'t</string>
|
||||
<!-- Content description (not visible, for screen readers etc.): button to close the collection creator -->
|
||||
<string name="create_collection_close">Nārán</string>
|
||||
|
||||
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
|
||||
<string name="create_collection_save">Nā\'nïnj sà\'</string>
|
||||
<!-- Snackbar action to view the collection the user just created or updated -->
|
||||
<string name="create_collection_view">Ni\'iāj</string>
|
||||
|
||||
<!-- Default name for a new collection in "name new collection" step of the collection creator. %d is a placeholder for the number of collections-->
|
||||
<string name="create_collection_default_name">Sa nachra chrē\'t %d</string>
|
||||
|
||||
<!-- Share -->
|
||||
<!-- Share screen header -->
|
||||
<string name="share_header">Gā\'nïnj gan\'an nī dūyinga\'</string>
|
||||
|
||||
<!-- Share screen header -->
|
||||
<string name="share_header_2">Dūyingô\'</string>
|
||||
<!-- Content description (not visible, for screen readers etc.):
|
||||
"Share" button. Opens the share menu when pressed. -->
|
||||
<string name="share_button_content_description">Dūyingô\'</string>
|
||||
<!-- Sub-header in the dialog to share a link to another app -->
|
||||
<string name="share_link_subheader">Dūyingô\' \'ngō lînk</string>
|
||||
<!-- Sub-header in the dialog to share a link to another sync device -->
|
||||
<string name="share_device_subheader">Gā\'nïnj riña aga\'</string>
|
||||
<!-- Sub-header in the dialog to share a link to an app from the full list -->
|
||||
<string name="share_link_all_apps_subheader">Daran\' sun huā</string>
|
||||
|
||||
<!-- Content description (not visible, for screen readers etc.): Close onboarding screen -->
|
||||
<string name="onboarding_close">Nārán</string>
|
||||
|
||||
|
|
|
@ -1432,4 +1432,9 @@
|
|||
<!-- Top Sites -->
|
||||
<!-- Title text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_title">Đã đạt đến giới hạn trang web hàng đầu</string>
|
||||
</resources>
|
||||
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_content">Để thêm một trang web hàng đầu mới, loại bỏ một cái cũ trước. Chạm và giữ trang web và chọn xóa.</string>
|
||||
<!-- Confirmation dialog button text when top sites limit is reached. -->
|
||||
<string name="top_sites_max_limit_confirmation_button">OK, đã hiểu</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<dimen name="crash_reporter_close_tab_button_bottom_margin">24dp</dimen>
|
||||
<dimen name="glyph_button_height">48dp</dimen>
|
||||
<dimen name="glyph_button_width">48dp</dimen>
|
||||
<dimen name="mozac_browser_menu_width_min" tools:ignore="UnusedResources">250dp</dimen>
|
||||
<dimen name="mozac_browser_menu_width_min" tools:ignore="UnusedResources">112dp</dimen>
|
||||
<dimen name="mozac_browser_menu_width_max" tools:ignore="UnusedResources">314dp</dimen>
|
||||
<dimen name="mozac_browser_menu_corner_radius">8dp</dimen>
|
||||
<dimen name="toolbar_elevation">7dp</dimen>
|
||||
|
|
|
@ -566,6 +566,8 @@
|
|||
<string name="bookmark_select_folder">Select folder</string>
|
||||
<!-- Confirmation message for a dialog confirming if the user wants to delete the selected folder -->
|
||||
<string name="bookmark_delete_folder_confirmation_dialog">Are you sure you want to delete this folder?</string>
|
||||
<!-- Confirmation message for a dialog confirming if the user wants to delete multiple items including folders. Parameter will be replaced by app name. -->
|
||||
<string name="bookmark_delete_multiple_folders_confirmation_dialog">%s will delete the selected items.</string>
|
||||
<!-- Snackbar title shown after a folder has been deleted. This first parameter is the name of the deleted folder -->
|
||||
<string name="bookmark_delete_folder_snackbar">Deleted %1$s</string>
|
||||
<!-- Screen title for adding a bookmarks folder -->
|
||||
|
@ -620,8 +622,10 @@
|
|||
<!-- Bookmark snackbar message on deletion
|
||||
The first parameter is the host part of the URL of the bookmark deleted, if any -->
|
||||
<string name="bookmark_deletion_snackbar_message">Deleted %1$s</string>
|
||||
<!-- Bookmark snackbar message on deleting multiple bookmarks -->
|
||||
<!-- Bookmark snackbar message on deleting multiple bookmarks not including folders-->
|
||||
<string name="bookmark_deletion_multiple_snackbar_message_2">Bookmarks deleted</string>
|
||||
<!-- Bookmark snackbar message on deleting multiple bookmarks including folders-->
|
||||
<string name="bookmark_deletion_multiple_snackbar_message_3">Deleting selected folders</string>
|
||||
<!-- Bookmark undo button for deletion snackbar action -->
|
||||
<string name="bookmark_undo_deletion">UNDO</string>
|
||||
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.addons
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.android.synthetic.main.fragment_add_on_details.view.*
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class AddonDetailsViewTest {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var interactor: AddonDetailsInteractor
|
||||
private lateinit var detailsView: AddonDetailsView
|
||||
private val baseAddon = Addon(
|
||||
id = "",
|
||||
translatableDescription = mapOf(
|
||||
Addon.DEFAULT_LOCALE to "Some blank addon\nwith a blank line"
|
||||
),
|
||||
updatedAt = "2020-11-23T08:00:00Z"
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext).inflate(R.layout.fragment_add_on_details, null)
|
||||
interactor = mockk(relaxed = true)
|
||||
|
||||
detailsView = AddonDetailsView(view, interactor)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons rating`() {
|
||||
detailsView.bind(baseAddon.copy(
|
||||
rating = null
|
||||
))
|
||||
assertEquals(0f, view.rating_view.rating)
|
||||
|
||||
detailsView.bind(baseAddon.copy(
|
||||
rating = Addon.Rating(
|
||||
average = 4.3f,
|
||||
reviews = 100
|
||||
)
|
||||
))
|
||||
assertEquals("4.30/5", view.rating_view.contentDescription)
|
||||
assertEquals(4.5f, view.rating_view.rating)
|
||||
assertEquals("100", view.users_count.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons website`() {
|
||||
detailsView.bind(baseAddon.copy(
|
||||
siteUrl = "https://mozilla.org"
|
||||
))
|
||||
|
||||
view.home_page_label.performClick()
|
||||
|
||||
verify { interactor.openWebsite(Uri.parse("https://mozilla.org")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons last updated`() {
|
||||
detailsView.bind(baseAddon)
|
||||
|
||||
assertEquals("Nov 23, 2020", view.last_updated_text.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons version`() {
|
||||
detailsView.bind(baseAddon.copy(
|
||||
version = "1.0.0",
|
||||
installedState = null
|
||||
))
|
||||
assertEquals("1.0.0", view.version_text.text)
|
||||
view.version_text.performLongClick()
|
||||
verify(exactly = 0) { interactor.showUpdaterDialog(any()) }
|
||||
|
||||
detailsView.bind(baseAddon.copy(
|
||||
version = "1.0.0",
|
||||
installedState = Addon.InstalledState(
|
||||
id = "",
|
||||
version = "2.0.0",
|
||||
optionsPageUrl = null
|
||||
)
|
||||
))
|
||||
assertEquals("2.0.0", view.version_text.text)
|
||||
view.version_text.performLongClick()
|
||||
verify { interactor.showUpdaterDialog(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons authors`() {
|
||||
val baseAuthor = Addon.Author("", "", "", "")
|
||||
detailsView.bind(baseAddon.copy(
|
||||
authors = listOf(
|
||||
baseAuthor.copy(name = " Sarah Jane"),
|
||||
baseAuthor.copy(name = "John Smith ")
|
||||
)
|
||||
))
|
||||
|
||||
assertEquals("Sarah Jane, John Smith", view.author_text.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons details`() {
|
||||
detailsView.bind(baseAddon)
|
||||
|
||||
assertEquals(
|
||||
"Some blank addon\nwith a blank line",
|
||||
view.details.text.toString()
|
||||
)
|
||||
assertTrue(view.details.movementMethod is LinkMovementMethod)
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ class BookmarkControllerTest {
|
|||
private val navController: NavController = mockk(relaxed = true)
|
||||
private val showSnackbar: (String) -> Unit = mockk(relaxed = true)
|
||||
private val deleteBookmarkNodes: (Set<BookmarkNode>, Event) -> Unit = mockk(relaxed = true)
|
||||
private val deleteBookmarkFolder: (BookmarkNode) -> Unit = mockk(relaxed = true)
|
||||
private val deleteBookmarkFolder: (Set<BookmarkNode>) -> Unit = mockk(relaxed = true)
|
||||
private val invokePendingDeletion: () -> Unit = mockk(relaxed = true)
|
||||
|
||||
private val homeActivity: HomeActivity = mockk(relaxed = true)
|
||||
|
@ -240,10 +240,10 @@ class BookmarkControllerTest {
|
|||
|
||||
@Test
|
||||
fun `handleBookmarkDeletion for a folder should properly call the delete folder delegate`() {
|
||||
controller.handleBookmarkFolderDeletion(subfolder)
|
||||
controller.handleBookmarkFolderDeletion(setOf(subfolder))
|
||||
|
||||
verify {
|
||||
deleteBookmarkFolder(subfolder)
|
||||
deleteBookmarkFolder(setOf(subfolder))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ class BookmarkFragmentInteractorTest {
|
|||
interactor.onDelete(setOf(subfolder))
|
||||
|
||||
verify {
|
||||
bookmarkController.handleBookmarkFolderDeletion(subfolder)
|
||||
bookmarkController.handleBookmarkFolderDeletion(setOf(subfolder))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,9 @@ class HistoryFragmentStoreTest {
|
|||
fun finishSync() = runBlocking {
|
||||
val initialState = HistoryFragmentState(
|
||||
items = listOf(),
|
||||
mode = HistoryFragmentState.Mode.Syncing
|
||||
mode = HistoryFragmentState.Mode.Syncing,
|
||||
pendingDeletionIds = emptySet(),
|
||||
isDeletingItems = false
|
||||
)
|
||||
val store = HistoryFragmentStore(initialState)
|
||||
|
||||
|
@ -71,16 +73,22 @@ class HistoryFragmentStoreTest {
|
|||
|
||||
private fun emptyDefaultState(): HistoryFragmentState = HistoryFragmentState(
|
||||
items = listOf(),
|
||||
mode = HistoryFragmentState.Mode.Normal
|
||||
mode = HistoryFragmentState.Mode.Normal,
|
||||
pendingDeletionIds = emptySet(),
|
||||
isDeletingItems = false
|
||||
)
|
||||
|
||||
private fun oneItemEditState(): HistoryFragmentState = HistoryFragmentState(
|
||||
items = listOf(),
|
||||
mode = HistoryFragmentState.Mode.Editing(setOf(historyItem))
|
||||
mode = HistoryFragmentState.Mode.Editing(setOf(historyItem)),
|
||||
pendingDeletionIds = emptySet(),
|
||||
isDeletingItems = false
|
||||
)
|
||||
|
||||
private fun twoItemEditState(): HistoryFragmentState = HistoryFragmentState(
|
||||
items = listOf(),
|
||||
mode = HistoryFragmentState.Mode.Editing(setOf(historyItem, newHistoryItem))
|
||||
mode = HistoryFragmentState.Mode.Editing(setOf(historyItem, newHistoryItem)),
|
||||
pendingDeletionIds = emptySet(),
|
||||
isDeletingItems = false
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
object AndroidComponents {
|
||||
const val VERSION = "45.0.20200616130058"
|
||||
const val VERSION = "47.0.20200617130048"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue