From 8f5a37733dbc3cff33a242cdeefd2f68be92d7c8 Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Wed, 22 Jul 2020 19:23:38 -0700 Subject: [PATCH 01/47] Create ToolbarPosition enum (#12747) --- .../fenix/browser/BaseBrowserFragment.kt | 13 ++-- .../mozilla/fenix/browser/BrowserAnimator.kt | 16 ++-- .../org/mozilla/fenix/cfr/SearchWidgetCFR.kt | 14 ++-- .../components/metrics/GleanMetricsService.kt | 8 +- .../components/toolbar/BrowserToolbarView.kt | 70 ++++++++--------- .../toolbar/TabCounterToolbarButton.kt | 7 +- .../components/toolbar/ToolbarPosition.kt | 19 +++++ .../org/mozilla/fenix/home/HomeFragment.kt | 78 +++++++++---------- ...boardingToolbarPositionPickerViewHolder.kt | 8 +- .../fenix/settings/CustomizationFragment.kt | 6 +- .../TrackingProtectionOverlay.kt | 14 ++-- .../java/org/mozilla/fenix/utils/Settings.kt | 4 + ...dingToolbarPositionPickerViewHolderTest.kt | 5 +- 13 files changed, 141 insertions(+), 121 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarPosition.kt diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 0c5387476..98f0fc53e 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -93,6 +93,7 @@ import org.mozilla.fenix.components.toolbar.BrowserToolbarViewInteractor import org.mozilla.fenix.components.toolbar.DefaultBrowserToolbarController import org.mozilla.fenix.components.toolbar.SwipeRefreshScrollingViewBehavior import org.mozilla.fenix.components.toolbar.ToolbarIntegration +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.downloads.DownloadService import org.mozilla.fenix.downloads.DynamicDownloadDialog import org.mozilla.fenix.ext.components @@ -264,7 +265,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session _browserToolbarView = BrowserToolbarView( container = view.browserLayout, - shouldUseBottomToolbar = context.settings().shouldUseBottomToolbar, + toolbarPosition = context.settings().toolbarPosition, interactor = browserInteractor, customTabSession = customTabSessionId?.let { sessionManager.findSessionById(it) }, lifecycleOwner = viewLifecycleOwner @@ -677,10 +678,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session private fun initializeEngineView(toolbarHeight: Int) { engineView.setDynamicToolbarMaxHeight(toolbarHeight) - val behavior = if (requireContext().settings().shouldUseBottomToolbar) { - EngineViewBottomBehavior(context, null) - } else { - SwipeRefreshScrollingViewBehavior(requireContext(), null, engineView, browserToolbarView) + val context = requireContext() + val behavior = when (context.settings().toolbarPosition) { + ToolbarPosition.BOTTOM -> EngineViewBottomBehavior(context, null) + ToolbarPosition.TOP -> SwipeRefreshScrollingViewBehavior(context, null, engineView, browserToolbarView) } (swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams).behavior = behavior @@ -843,7 +844,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session * Returns the layout [android.view.Gravity] for the quick settings and ETP dialog. */ protected fun getAppropriateLayoutGravity(): Int = - if (context?.settings()?.shouldUseBottomToolbar == true) Gravity.BOTTOM else Gravity.TOP + context?.settings()?.toolbarPosition?.androidGravity ?: Gravity.BOTTOM /** * Updates the site permissions rules based on user settings. diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt index 5bb2fc83f..02a94f2d1 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import mozilla.components.concept.engine.EngineView import org.mozilla.fenix.R +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.settings import java.lang.ref.WeakReference @@ -155,12 +156,15 @@ class BrowserAnimator( fun getToolbarNavOptions(context: Context): NavOptions { val navOptions = NavOptions.Builder() - if (!context.settings().shouldUseBottomToolbar) { - navOptions.setEnterAnim(R.anim.fade_in) - navOptions.setExitAnim(R.anim.fade_out) - } else { - navOptions.setEnterAnim(R.anim.fade_in_up) - navOptions.setExitAnim(R.anim.fade_out_down) + when (context.settings().toolbarPosition) { + ToolbarPosition.TOP -> { + navOptions.setEnterAnim(R.anim.fade_in) + navOptions.setExitAnim(R.anim.fade_out) + } + ToolbarPosition.BOTTOM -> { + navOptions.setEnterAnim(R.anim.fade_in_up) + navOptions.setExitAnim(R.anim.fade_out_down) + } } return navOptions.build() diff --git a/app/src/main/java/org/mozilla/fenix/cfr/SearchWidgetCFR.kt b/app/src/main/java/org/mozilla/fenix/cfr/SearchWidgetCFR.kt index 1bbe94e05..07d017ce0 100644 --- a/app/src/main/java/org/mozilla/fenix/cfr/SearchWidgetCFR.kt +++ b/app/src/main/java/org/mozilla/fenix/cfr/SearchWidgetCFR.kt @@ -11,7 +11,6 @@ import android.graphics.drawable.ColorDrawable import android.view.Gravity import android.view.LayoutInflater import android.view.View -import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.marginTop import kotlinx.android.synthetic.main.search_widget_cfr.view.* @@ -21,6 +20,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.components.SearchWidgetCreator import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.utils.Settings /** @@ -50,18 +50,14 @@ class SearchWidgetCFR( val searchWidgetCFRDialog = Dialog(context) val layout = LayoutInflater.from(context) .inflate(R.layout.search_widget_cfr, null) - val isBottomToolbar = settings.shouldUseBottomToolbar + val toolbarPosition = settings.toolbarPosition - layout.drop_down_triangle.isGone = isBottomToolbar - layout.pop_up_triangle.isVisible = isBottomToolbar + layout.drop_down_triangle.isVisible = toolbarPosition == ToolbarPosition.TOP + layout.pop_up_triangle.isVisible = toolbarPosition == ToolbarPosition.BOTTOM val toolbar = getToolbar() - val gravity = if (isBottomToolbar) { - Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM - } else { - Gravity.CENTER_HORIZONTAL or Gravity.TOP - } + val gravity = Gravity.CENTER_HORIZONTAL or toolbarPosition.androidGravity layout.cfr_neg_button.setOnClickListener { metrics.track(Event.SearchWidgetCFRNotNowPressed) diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 677e0aba7..4bf89abbd 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -50,6 +50,7 @@ import org.mozilla.fenix.GleanMetrics.TopSites import org.mozilla.fenix.GleanMetrics.TrackingProtection import org.mozilla.fenix.GleanMetrics.UserSpecifiedSearchEngines import org.mozilla.fenix.GleanMetrics.VoiceSearch +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.utils.BrowsersCache @@ -724,10 +725,9 @@ class GleanMetricsService(private val context: Context) : MetricsService { } toolbarPosition.set( - if (context.settings().shouldUseBottomToolbar) { - Event.ToolbarPositionChanged.Position.BOTTOM.name - } else { - Event.ToolbarPositionChanged.Position.TOP.name + when (context.settings().toolbarPosition) { + ToolbarPosition.BOTTOM -> Event.ToolbarPositionChanged.Position.BOTTOM.name + ToolbarPosition.TOP -> Event.ToolbarPositionChanged.Position.TOP.name } ) } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index c5011f1e5..d725a9f3d 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -17,6 +17,7 @@ import androidx.annotation.VisibleForTesting import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat import androidx.core.view.isVisible +import androidx.core.view.updateLayoutParams import androidx.lifecycle.LifecycleOwner import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS @@ -59,7 +60,7 @@ interface BrowserToolbarViewInteractor { @SuppressWarnings("LargeClass") class BrowserToolbarView( private val container: ViewGroup, - private val shouldUseBottomToolbar: Boolean, + private val toolbarPosition: ToolbarPosition, private val interactor: BrowserToolbarViewInteractor, private val customTabSession: Session?, private val lifecycleOwner: LifecycleOwner @@ -71,9 +72,9 @@ class BrowserToolbarView( private val settings = container.context.settings() @LayoutRes - private val toolbarLayout = when { - settings.shouldUseBottomToolbar -> R.layout.component_bottom_browser_toolbar - else -> R.layout.component_browser_top_toolbar + private val toolbarLayout = when (settings.toolbarPosition) { + ToolbarPosition.BOTTOM -> R.layout.component_bottom_browser_toolbar + ToolbarPosition.TOP -> R.layout.component_browser_top_toolbar } private val layout = LayoutInflater.from(container.context) @@ -144,7 +145,7 @@ class BrowserToolbarView( with(container.context) { val sessionManager = components.core.sessionManager - if (!shouldUseBottomToolbar) { + if (toolbarPosition == ToolbarPosition.TOP) { val offsetChangedListener = AppBarLayout.OnOffsetChangedListener { _: AppBarLayout?, verticalOffset: Int -> interactor.onScrolled(verticalOffset) @@ -167,10 +168,9 @@ class BrowserToolbarView( false } - display.progressGravity = if (shouldUseBottomToolbar) { - DisplayToolbar.Gravity.TOP - } else { - DisplayToolbar.Gravity.BOTTOM + display.progressGravity = when (toolbarPosition) { + ToolbarPosition.BOTTOM -> DisplayToolbar.Gravity.TOP + ToolbarPosition.TOP -> DisplayToolbar.Gravity.BOTTOM } val primaryTextColor = ContextCompat.getColor( @@ -207,7 +207,7 @@ class BrowserToolbarView( this, sessionManager, customTabSession?.id, - shouldReverseItems = !shouldUseBottomToolbar, + shouldReverseItems = toolbarPosition == ToolbarPosition.TOP, onItemTapped = { interactor.onBrowserToolbarMenuItemTapped(it) } @@ -216,7 +216,7 @@ class BrowserToolbarView( menuToolbar = DefaultToolbarMenu( context = this, hasAccountProblem = components.backgroundServices.accountManager.accountNeedsReauth(), - shouldReverseItems = !shouldUseBottomToolbar, + shouldReverseItems = toolbarPosition == ToolbarPosition.TOP, onItemTapped = { interactor.onBrowserToolbarMenuItemTapped(it) }, lifecycleOwner = lifecycleOwner, sessionManager = sessionManager, @@ -254,12 +254,15 @@ class BrowserToolbarView( } fun expand() { - if (settings.shouldUseBottomToolbar) { - (view.layoutParams as CoordinatorLayout.LayoutParams).apply { - (behavior as BrowserToolbarBottomBehavior).forceExpand(view) + when (settings.toolbarPosition) { + ToolbarPosition.BOTTOM -> { + (view.layoutParams as CoordinatorLayout.LayoutParams).apply { + (behavior as BrowserToolbarBottomBehavior).forceExpand(view) + } + } + ToolbarPosition.TOP -> { + layout.app_bar?.setExpanded(true) } - } else if (!settings.shouldUseBottomToolbar) { - layout.app_bar?.setExpanded(true) } } @@ -268,30 +271,27 @@ class BrowserToolbarView( * Note that the bottom toolbar has a feature flag for being dynamic, so it may not get flags set. */ fun setScrollFlags(shouldDisableScroll: Boolean = false) { - if (view.context.settings().shouldUseBottomToolbar) { - if (view.layoutParams is CoordinatorLayout.LayoutParams) { - (view.layoutParams as CoordinatorLayout.LayoutParams).apply { + when (settings.toolbarPosition) { + ToolbarPosition.BOTTOM -> { + (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { behavior = BrowserToolbarBottomBehavior(view.context, null) } } - - return - } - - val params = view.layoutParams as AppBarLayout.LayoutParams - - params.scrollFlags = when (view.context.settings().shouldUseFixedTopToolbar || shouldDisableScroll) { - true -> { - // Force expand the toolbar so the user is not stuck with a hidden toolbar - expand() - 0 - } - false -> { - SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS or SCROLL_FLAG_SNAP or SCROLL_FLAG_EXIT_UNTIL_COLLAPSED + ToolbarPosition.TOP -> { + view.updateLayoutParams { + scrollFlags = if (settings.shouldUseFixedTopToolbar || shouldDisableScroll) { + // Force expand the toolbar so the user is not stuck with a hidden toolbar + expand() + 0 + } else { + SCROLL_FLAG_SCROLL or + SCROLL_FLAG_ENTER_ALWAYS or + SCROLL_FLAG_SNAP or + SCROLL_FLAG_EXIT_UNTIL_COLLAPSED + } + } } } - - view.layoutParams = params } companion object { diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/TabCounterToolbarButton.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/TabCounterToolbarButton.kt index f8739c2ad..e282e23a2 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/TabCounterToolbarButton.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/TabCounterToolbarButton.kt @@ -113,10 +113,9 @@ class TabCounterToolbarButton( ) return BrowserMenuBuilder( - if (context.settings().shouldUseBottomToolbar) { - menuItems.reversed() - } else { - menuItems + when (context.settings().toolbarPosition) { + ToolbarPosition.BOTTOM -> menuItems.reversed() + ToolbarPosition.TOP -> menuItems } ).build(context) } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarPosition.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarPosition.kt new file mode 100644 index 000000000..b69b6fef8 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarPosition.kt @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.components.toolbar + +import android.view.Gravity + +/** + * Fenix lets the browser toolbar be placed at either the top or the bottom of the screen. + * This enum represents the posible positions. + * + * @property androidGravity [Gravity] value corresponding to the position. + * Used to position related elements such as a CFR tooltip. + */ +enum class ToolbarPosition(val androidGravity: Int) { + BOTTOM(Gravity.BOTTOM), + TOP(Gravity.TOP) +} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 0f3d75878..f147c9371 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -83,6 +83,7 @@ import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.tips.FenixTipManager import org.mozilla.fenix.components.tips.providers.MigrationTipProvider +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.hideToolbar import org.mozilla.fenix.ext.metrics @@ -120,12 +121,9 @@ class HomeFragment : Fragment() { } private val snackbarAnchorView: View? - get() { - return if (requireContext().settings().shouldUseBottomToolbar) { - toolbarLayout - } else { - null - } + get() = when (requireContext().settings().toolbarPosition) { + ToolbarPosition.BOTTOM -> toolbarLayout + ToolbarPosition.TOP -> null } private val browsingModeManager get() = (activity as HomeActivity).browsingModeManager @@ -253,45 +251,45 @@ class HomeFragment : Fragment() { } private fun updateLayout(view: View) { - val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar - - if (!shouldUseBottomToolbar) { - view.toolbarLayout.layoutParams = CoordinatorLayout.LayoutParams( - ConstraintLayout.LayoutParams.MATCH_PARENT, - ConstraintLayout.LayoutParams.WRAP_CONTENT - ) - .apply { + when (view.context.settings().toolbarPosition) { + ToolbarPosition.TOP -> { + view.toolbarLayout.layoutParams = CoordinatorLayout.LayoutParams( + ConstraintLayout.LayoutParams.MATCH_PARENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT + ).apply { gravity = Gravity.TOP } - ConstraintSet().apply { - clone(view.toolbarLayout) - clear(view.bottom_bar.id, BOTTOM) - clear(view.bottomBarShadow.id, BOTTOM) - connect(view.bottom_bar.id, TOP, PARENT_ID, TOP) - connect(view.bottomBarShadow.id, TOP, view.bottom_bar.id, BOTTOM) - connect(view.bottomBarShadow.id, BOTTOM, PARENT_ID, BOTTOM) - applyTo(view.toolbarLayout) + ConstraintSet().apply { + clone(view.toolbarLayout) + clear(view.bottom_bar.id, BOTTOM) + clear(view.bottomBarShadow.id, BOTTOM) + connect(view.bottom_bar.id, TOP, PARENT_ID, TOP) + connect(view.bottomBarShadow.id, TOP, view.bottom_bar.id, BOTTOM) + connect(view.bottomBarShadow.id, BOTTOM, PARENT_ID, BOTTOM) + applyTo(view.toolbarLayout) + } + + view.bottom_bar.background = resources.getDrawable( + ThemeManager.resolveAttribute(R.attr.bottomBarBackgroundTop, requireContext()), + null + ) + + view.homeAppBar.updateLayoutParams { + topMargin = HEADER_MARGIN.dpToPx(resources.displayMetrics) + } + + createNewAppBarListener(HEADER_MARGIN.dpToPx(resources.displayMetrics).toFloat()) + view.homeAppBar.addOnOffsetChangedListener( + homeAppBarOffSetListener + ) } - - view.bottom_bar.background = resources.getDrawable( - ThemeManager.resolveAttribute(R.attr.bottomBarBackgroundTop, requireContext()), - null - ) - - view.homeAppBar.updateLayoutParams { - topMargin = HEADER_MARGIN.dpToPx(resources.displayMetrics) + ToolbarPosition.BOTTOM -> { + createNewAppBarListener(0F) + view.homeAppBar.addOnOffsetChangedListener( + homeAppBarOffSetListener + ) } - - createNewAppBarListener(HEADER_MARGIN.dpToPx(resources.displayMetrics).toFloat()) - view.homeAppBar.addOnOffsetChangedListener( - homeAppBarOffSetListener - ) - } else { - createNewAppBarListener(0F) - view.homeAppBar.addOnOffsetChangedListener( - homeAppBarOffSetListener - ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolder.kt index 87c3453ee..b484a8d3b 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolder.kt @@ -10,6 +10,7 @@ import kotlinx.android.synthetic.main.onboarding_toolbar_position_picker.view.* import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event.OnboardingToolbarPosition.Position +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.asActivity import org.mozilla.fenix.ext.components import org.mozilla.fenix.onboarding.OnboardingRadioButton @@ -29,10 +30,9 @@ class OnboardingToolbarPositionPickerViewHolder(view: View) : RecyclerView.ViewH radioBottomToolbar.addIllustration(view.toolbar_bottom_image) val settings = view.context.components.settings - radio = if (settings.shouldUseBottomToolbar) { - radioBottomToolbar - } else { - radioTopToolbar + radio = when (settings.toolbarPosition) { + ToolbarPosition.BOTTOM -> radioBottomToolbar + ToolbarPosition.TOP -> radioTopToolbar } radio.updateRadioValue(true) diff --git a/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt index d894e5514..3d586befd 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt @@ -12,6 +12,7 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.preference.PreferenceFragmentCompat import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings @@ -122,8 +123,9 @@ class CustomizationFragment : PreferenceFragmentCompat() { )) } - topPreference.setCheckedWithoutClickListener(!requireContext().settings().shouldUseBottomToolbar) - bottomPreference.setCheckedWithoutClickListener(requireContext().settings().shouldUseBottomToolbar) + val toolbarPosition = requireContext().settings().toolbarPosition + topPreference.setCheckedWithoutClickListener(toolbarPosition == ToolbarPosition.TOP) + bottomPreference.setCheckedWithoutClickListener(toolbarPosition == ToolbarPosition.BOTTOM) addToRadioGroup(topPreference, bottomPreference) } diff --git a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt index 91916c768..8ed15bf03 100644 --- a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt @@ -13,7 +13,6 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.widget.ImageView -import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.marginTop import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.* @@ -22,6 +21,7 @@ import mozilla.components.browser.session.Session import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.increaseTapArea import org.mozilla.fenix.utils.Settings @@ -63,10 +63,10 @@ class TrackingProtectionOverlay( val layout = LayoutInflater.from(context) .inflate(R.layout.tracking_protection_onboarding_popup, null) - val isBottomToolbar = settings.shouldUseBottomToolbar + val toolbarPosition = settings.toolbarPosition - layout.drop_down_triangle.isGone = isBottomToolbar - layout.pop_up_triangle.isVisible = isBottomToolbar + layout.drop_down_triangle.isVisible = toolbarPosition == ToolbarPosition.TOP + layout.pop_up_triangle.isVisible = toolbarPosition == ToolbarPosition.BOTTOM layout.onboarding_message.text = context.getString( @@ -91,11 +91,7 @@ class TrackingProtectionOverlay( val xOffset = triangleMarginStartPx + triangleWidthPx / 2 - val gravity = if (isBottomToolbar) { - Gravity.START or Gravity.BOTTOM - } else { - Gravity.START or Gravity.TOP - } + val gravity = Gravity.START or toolbarPosition.androidGravity trackingOnboardingDialog.apply { setContentView(layout) diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index cb88d7579..e5e21dbdc 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -29,6 +29,7 @@ import org.mozilla.fenix.Config import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.metrics.MozillaProductDetector +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.settings.PhoneFeature @@ -463,6 +464,9 @@ class Settings(private val appContext: Context) : PreferencesHolder { default = !touchExplorationIsEnabled && !switchServiceIsEnabled ) + val toolbarPosition: ToolbarPosition + get() = if (shouldUseBottomToolbar) ToolbarPosition.BOTTOM else ToolbarPosition.TOP + /** * Check each active accessibility service to see if it can perform gestures, if any can, * then it is *likely* a switch service is enabled. We are assuming this to be the case based on #7486 diff --git a/app/src/test/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolderTest.kt index 93636ec77..414871a69 100644 --- a/app/src/test/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingToolbarPositionPickerViewHolderTest.kt @@ -15,6 +15,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.ext.components +import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.utils.Settings @@ -34,7 +35,7 @@ class OnboardingToolbarPositionPickerViewHolderTest { @Test fun `bottom illustration should select corresponding radio button`() { - every { settings.shouldUseBottomToolbar } returns false + every { settings.toolbarPosition } returns ToolbarPosition.TOP OnboardingToolbarPositionPickerViewHolder(view) assertTrue(view.toolbar_top_radio_button.isChecked) assertFalse(view.toolbar_bottom_radio_button.isChecked) @@ -46,7 +47,7 @@ class OnboardingToolbarPositionPickerViewHolderTest { @Test fun `top illustration should select corresponding radio button`() { - every { settings.shouldUseBottomToolbar } returns true + every { settings.toolbarPosition } returns ToolbarPosition.BOTTOM OnboardingToolbarPositionPickerViewHolder(view) assertFalse(view.toolbar_top_radio_button.isChecked) assertTrue(view.toolbar_bottom_radio_button.isChecked) From 7f829e175285ab5d77d500d4cba3b092871a3df6 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Thu, 23 Jul 2020 00:12:58 +0000 Subject: [PATCH 02/47] Import l10n. --- app/src/main/res/values-cy/strings.xml | 16 ++++++++- app/src/main/res/values-de/strings.xml | 16 ++++++++- app/src/main/res/values-dsb/strings.xml | 39 ++++++++++++++------ app/src/main/res/values-es-rCL/strings.xml | 39 +++++++++++++++----- app/src/main/res/values-es-rES/strings.xml | 16 ++++++++- app/src/main/res/values-fy-rNL/strings.xml | 18 ++++++++-- app/src/main/res/values-hsb/strings.xml | 39 ++++++++++++++------ app/src/main/res/values-it/strings.xml | 16 ++++++++- app/src/main/res/values-iw/strings.xml | 16 ++++++++- app/src/main/res/values-kab/strings.xml | 18 ++++++++-- app/src/main/res/values-nb-rNO/strings.xml | 23 +++++++----- app/src/main/res/values-nn-rNO/strings.xml | 41 +++++++++++++++------- app/src/main/res/values-oc/strings.xml | 18 +++++++++- app/src/main/res/values-pl/strings.xml | 39 +++++++++++++++----- app/src/main/res/values-pt-rPT/strings.xml | 18 ++++++++-- app/src/main/res/values-sl/strings.xml | 37 ++++++++++++++----- app/src/main/res/values-sr/strings.xml | 39 ++++++++++++++------ app/src/main/res/values-sv-rSE/strings.xml | 23 +++++++----- app/src/main/res/values-te/strings.xml | 16 ++++++++- app/src/main/res/values-uk/strings.xml | 39 +++++++++++++++----- 20 files changed, 416 insertions(+), 110 deletions(-) diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index f89c38d6f..422797ffb 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -576,6 +576,8 @@ Dewis ffolder Ydych chi’n siŵr eich bod am ddileu’r ffolder yma? + + Bydd %s yn dileu’r eitemau hyn. Wedi dileu %1$s @@ -631,8 +633,10 @@ The first parameter is the host part of the URL of the bookmark deleted, if any --> Wedi dileu %1$s - + Wedi dileu Nodau Tudalen + + Yn dileu’r nodau tudalen hyn DADWNEUD @@ -725,6 +729,8 @@ %d tab wedi’i ddewis Tabiau wedi’u cadw! + + Casgliad wedi’i gadw! Tab wedi’i gadw! @@ -830,6 +836,10 @@ GWRTHOD Ydych chi’n siŵr eich bod am ddileu %1$s? + + Bydd dileu’r tab hwn yn dileu’r casgliad cyfan. Gallwch greu casgliadau newydd ar unrhyw adeg. + + Dileu %1$s? Dileu @@ -1228,6 +1238,8 @@ Fodd bynnag, gall fod yn llai sefydlog. Llwythwch ein porwr beta i gael profiad Bydd mewngofnodion a chyfrineiriau sydd heb eu cadw i’w gweld yma. Ni fydd mewngofnodion a chyfrineiriau’n cael eu cadw ar gyfer y gwefannau hyn. + + Dileu pob eithriad Chwilio mewngofnodion @@ -1267,6 +1279,8 @@ Fodd bynnag, gall fod yn llai sefydlog. Llwythwch ein porwr beta i gael profiad Copïo’r enw defnyddiwr Copïo’r wefan + + Agor y wefan yn y porwr Dangos cyfrinair diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 673a112f6..c2c3ec46a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -589,6 +589,8 @@ Ordner auswählen Soll dieser Ordner wirklich gelöscht werden? + + %s wird die ausgewählten Elemente löschen. %1$s gelöscht @@ -646,8 +648,10 @@ %1$s gelöscht - + Lesezeichen gelöscht + + Ausgewählte Ordner werden gelöscht RÜCKGÄNGIG @@ -751,6 +755,8 @@ Tabs gespeichert + + Sammlung gespeichert! Tab gespeichert @@ -862,6 +868,10 @@ VERWEIGERN Soll %1$s wirklich gelöscht werden? + + Durch Löschen dieses Tabs wird die gesamte Sammlung gelöscht. Sie können jederzeit neue Sammlungen erstellen. + + %1$s löschen? Löschen @@ -1263,6 +1273,8 @@ Zugangsdaten und Passwörter, die nicht gespeichert werden, werden hier angezeigt. Zugangsdaten und Passwörter werden für diese Websites nicht gespeichert. + + Alle Ausnahmen löschen Zugangsdaten durchsuchen @@ -1301,6 +1313,8 @@ Benutzernamen kopieren Website kopieren + + Website im Browser öffnen Passwort anzeigen diff --git a/app/src/main/res/values-dsb/strings.xml b/app/src/main/res/values-dsb/strings.xml index 2b98ca1b3..b9013af97 100644 --- a/app/src/main/res/values-dsb/strings.xml +++ b/app/src/main/res/values-dsb/strings.xml @@ -149,13 +149,11 @@ Scannowaś - Skrotconki + Pytnica Nastajenja pytnicow - - Pytaś z - Něnto pytaś z: + Něnto pytaś z: Wótkaz z mjazywótkłada zasajźiś @@ -263,8 +261,8 @@ Wuwijarske rědy Daloke pytanje zmólkow pśez USB - - Pytańske skrotconki pokazaś + + Pytnice pokazaś Pytańske naraźenja pokazaś @@ -579,6 +577,8 @@ Zarědnik wubraś Cośo napšawdu toś ten zarědnik wulašowaś? + + %s wubrane zapiski wulašujo. %1$s jo se wulašował @@ -634,8 +634,10 @@ %1$s wulašowany - + Cytańske znamjenja su se wulašowali + + Wubrane zarědniki se lašuju ANULĚROWAŚ @@ -728,6 +730,8 @@ %d rejtarik wubrany Rejtariki su skłaźone! + + Zběrka skłaźona! Rejtarik jo skłaźony! @@ -832,6 +836,10 @@ WÓTPOKAZAŚ Cośo napšawdu %1$s lašowaś? + + Gaž toś ten rejtarik wulašujośo, se ceła zběrka wulašujo. Móžośo kuždy cas nowe zběrki napóraś. + + %1$s lašowaś? Lašowaś @@ -886,8 +894,6 @@ Wulašujo pśeglědowańske daty awtomatiski, gaž „Skóńcyś“ z głownego menija wuběraśo Wulašujo pśeglědowańske daty awtomatiski, gaž „Skóńcyś“ z głownego menija wuběraśo - - Pśeglědowańska historija Skóńcyś @@ -1235,6 +1241,8 @@ Pśizjawjenja a gronidła, kótarež se njeskładuju, se how pokažu. Pśizjawjenja a gronidła se za toś te sedła njeskładuju. + + Wšykne wuwześa wulašowaś Pśizjawjenja pytaś @@ -1274,6 +1282,8 @@ Wužywaŕske mě kopěrowaś Sedło kopěrowaś + + Sedło we wobglědowaku wócyniś Gronidło pokazaś @@ -1449,4 +1459,13 @@ W pórěźe, som zrozměł - + + + Skrotconki + + Pytaś z + + Něnto pytaś z: + + Pytańske skrotconki pokazaś + diff --git a/app/src/main/res/values-es-rCL/strings.xml b/app/src/main/res/values-es-rCL/strings.xml index 6dda574a4..6c6bc6ada 100644 --- a/app/src/main/res/values-es-rCL/strings.xml +++ b/app/src/main/res/values-es-rCL/strings.xml @@ -147,14 +147,11 @@ Escanear - Atajos + Motor de búsqueda Ajustes del motor de búsqueda - - Buscar con - Esta vez, buscar con: - + Esta vez, buscar con: Rellenar enlace desde el portapapeles @@ -262,8 +259,8 @@ Herramientas de desarrollador Depuración remota vía USB - - Mostrar atajos de búsqueda + + Mostrar motores de búsqueda Mostrar sugerencias de búsqueda @@ -577,6 +574,8 @@ Seleccionar carpeta ¿Estás seguro de querer borrar esta carpeta? + + %s eliminará los elementos seleccionados. %1$s eliminado @@ -631,8 +630,10 @@ %1$s eliminado - + Marcadores eliminados + + Eliminando carpetas seleccionadas DESHACER @@ -725,6 +726,8 @@ %d pestaña seleccionada ¡Pestañas guardadas! + + Colección guardada ¡Pestaña guardada! @@ -830,6 +833,10 @@ DENEGAR ¿Estás seguro de que deseas eliminar %1$s? + + Eliminar esta pestaña eliminará toda la colección. Puedes crear nuevas colecciones en cualquier momento. + + ¿Eliminar %1$s? Eliminar @@ -1230,6 +1237,8 @@ Las credenciales y contraseñas que no son guardadas serán mostradas aquí. Las credenciales y contraseñas no serán guardadas para estos sitios. + + Eliminar todas las excepciones Buscar credenciales @@ -1268,6 +1277,8 @@ Copiar nombre de usuario Copiar sitio + + Abrir sitio en el navegador Mostrar contraseña @@ -1442,4 +1453,14 @@ Ok, ¡ya caché! - + + + Atajos + + Buscar con + + Esta vez, buscar con: + + + Mostrar atajos de búsqueda + diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 597297acd..1b5521080 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -589,6 +589,8 @@ Seleccionar carpeta ¿Seguro que quieres eliminar esta carpeta? + + %s va a eliminar los elementos seleccionados. Se ha eliminado %1$s @@ -644,8 +646,10 @@ Se eliminó %1$s - + Marcadores eliminados + + Eliminar carpetas seleccionadas DESHACER @@ -749,6 +753,8 @@ ¡Pestañas guardadas! + + ¡Colección guardada! ¡Pestaña guardada! @@ -860,6 +866,10 @@ DENEGAR ¿Seguro que quieres eliminar %1$s? + + Eliminar esta pestaña va a eliminar toda la colección. Puedes crear nuevas colecciones en cualquier momento. + + ¿Eliminar %1$s? Eliminar @@ -1264,6 +1274,8 @@ Los inicios de sesión y contraseñas no guardados aparecerán aquí. No se guardarán los inicios de sesión y contraseñas para estos sitios. + + Eliminar todas las excepciones Buscar inicios de sesión @@ -1302,6 +1314,8 @@ Copiar nombre de usuario Copiar sitio + + Abrir sitio en el navegador Mostrar contraseña diff --git a/app/src/main/res/values-fy-rNL/strings.xml b/app/src/main/res/values-fy-rNL/strings.xml index 9971f3f13..42b5bfb19 100644 --- a/app/src/main/res/values-fy-rNL/strings.xml +++ b/app/src/main/res/values-fy-rNL/strings.xml @@ -577,6 +577,8 @@ Map selektearje Binne jo wis dat jo dizze map fuortsmite wolle? + + %s sil de selektearre items fuortsmite. %1$s fuortsmiten @@ -631,8 +633,10 @@ %1$s fuortsmiten - + Blêdwizers fuortsmiten + + Selektearre mappen fuortsmite UNGEDIEN MEITSJE @@ -725,6 +729,8 @@ %d ljepblêd selektearre Ljepblêden bewarre! + + Kolleksje bewarre! Ljepblêd bewarre! @@ -831,6 +837,10 @@ Binne jo wis dat jo %1$s fuortsmite wolle? + + As jo dit ljepblêd fuortsmite, wurdt de hiele kolleksje fuortsmiten. Jo kinne op elk momint nije kolleksjes meitsje. + + %1$s fuortsmite? Fuortsmite @@ -886,8 +896,6 @@ Smyt automatysk navigaasjegegevens fuort wannear\'t jo yn it haadmenu ‘Ofslute’ selektearje Smyt automatysk navigaasjegegevens fuort wannear\'t jo yn it haadmenu ‘Ofslute’ selektearje - - Navigaasjeskiednis Ofslute @@ -1233,6 +1241,8 @@ Net-bewarre oanmeldingen en wachtwurden wurde hjir werjûn. Oanmeldingen en wachtwurden wurde foar dizze websites net bewarre. + + Alle útsûnderingen fuortsmite Oanmeldingen sykje @@ -1271,6 +1281,8 @@ Brûkersnamme kopiearje Website kopiearje + + Website iepenje yn browser Wachtwurd toane diff --git a/app/src/main/res/values-hsb/strings.xml b/app/src/main/res/values-hsb/strings.xml index a2e5b9610..d2ed79c9f 100644 --- a/app/src/main/res/values-hsb/strings.xml +++ b/app/src/main/res/values-hsb/strings.xml @@ -149,13 +149,11 @@ Skenować - Skrótšenki + Pytawa Nastajenja pytawy - - Pytać z - Nětko pytać z: + Nětko pytać z: Wotkaz z mjezyskłada zasadźić @@ -263,8 +261,8 @@ Wuwiwarske nastroje Zdalene pytanje zmylkow přez USB - - Pytanske skrótšenki pokazać + + Pytawy pokazać Pytanske namjety pokazać @@ -578,6 +576,8 @@ Rjadowak wubrać Chceće woprawdźe tutón rjadowak zhašeć? + + %s wubrane zapiski zhaša. %1$s je so zhašał @@ -633,8 +633,10 @@ %1$s zhašany - + Zapołožki su so zhašeli + + Wubrane rjadowaki zhašeć COFNYĆ @@ -727,6 +729,8 @@ %d rajtark wubrany Rajtarki su składowane! + + Zběrka je składowana! Rajtark je składowany! @@ -832,6 +836,10 @@ WOTPOKAZAĆ Chceće woprawdźe %1$s zhašeć? + + Hdyž tutón rajtark zhašeće, so cyła zběrka zhaša. Móžeće kóždy čas nowe zběrki wutworić. + + %1$s zhašeć? Zhašeć @@ -887,8 +895,6 @@ Zhaša přehladowanske daty awtomatisce, hdyž „Skónčić“ z hłowneho menija wuběraće Zhaša přehladowanske daty awtomatisce, hdyž „Skónčić“ z hłowneho menija wuběraće - - Přehladowanska historija Skónčić @@ -1233,6 +1239,8 @@ Přizjewjenja a hesła, kotrež so njeskładuja, so tu pokazaja. Přizjewjenja a hesła so za tute sydła njeskładuja. + + Wšě wuwzaća zhašeć Přizjewjenja pytać @@ -1271,6 +1279,8 @@ Wužiwarske mjeno kopěrować Sydło kopěrować + + Sydło we wobhladowaku wočinić Hesło pokazać @@ -1447,4 +1457,13 @@ W porjadku, sym zrozumił - + + + Skrótšenki + + Pytać z + + Nětko pytać z: + + Pytanske skrótšenki pokazać + diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 1cca008f9..5e5d2b00d 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -592,6 +592,8 @@ Seleziona cartella Eliminare questa cartella? + + %s eliminerà gli elementi selezionati. %1$s eliminata @@ -647,8 +649,10 @@ Eliminato %1$s - + Segnalibri eliminati + + Eliminazione cartelle selezionate ANNULLA @@ -752,6 +756,8 @@ Schede salvate. + + Raccolta salvata. Scheda salvata. @@ -864,6 +870,10 @@ NEGA Eliminare %1$s? + + L’eliminazione di questa scheda rimuoverà l’intera raccolta. Puoi creare nuove raccolte in qualsiasi momento. + + Eliminare %1$s? Elimina @@ -1265,6 +1275,8 @@ Le credenziali e le password non salvate verranno mostrate qui. Le credenziali e le password non verranno salvate per questi siti. + + Elimina tutte le eccezioni Cerca credenziali @@ -1303,6 +1315,8 @@ Copia nome utente Copia sito + + Apri sito nel browser Mostra password diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index a15a0ac57..dacb1a106 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -564,6 +564,8 @@ בחירת תיקייה האם ברצונך למחוק תיקייה זו? + + ‏%s ימחק את הפריטים שנבחרו. נמחק %1$s @@ -619,8 +621,10 @@ נמחק %1$s - + הסימניות נמחקו + + בתהליך מחיקת התיקיות שנבחרו ביטול @@ -711,6 +715,8 @@ לשונית אחת נבחרה הלשוניות נשמרו! + + האוסף נשמר! הלשונית נשמרה! @@ -817,6 +823,10 @@ לחסום האם ברצונך למחוק את %1$s? + + מחיקת לשונית זו תמחק את האוסף כולו. באפשרותך ליצור אוספים חדשים בכל עת. + + למחוק את %1$s? מחיקה @@ -1207,6 +1217,8 @@ כניסות וססמאות שאינן שמורות יופיעו כאן. כניסות וססמאות לא יישמרו עבור אתרים אלו. + + מחיקת כל החריגות חיפוש כניסות @@ -1243,6 +1255,8 @@ העתקת שם משתמש העתקת אתר + + פתיחת אתר בדפדפן הצגת ססמה diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index 0500d96e7..d49539e2b 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -580,6 +580,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Fren akaram Tebɣiḍ ad tekseḍ akaram-agi? + + %s ad ikkes iferdisen ittwafernen. %1$s4 yettwakkes @@ -635,8 +637,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Kkes %1$s - + Ticraḍ n isebtar ttwakksent + + Tukksa n ikaramen ittwafernen UƔAL @@ -731,6 +735,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara %d n yiccer yettwafren Accaren ttwaskelsen! + + Tagrumma tettwasekles! Iccer yettwaselkes! @@ -837,6 +843,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara GDEL Tebɣiḍ ad tekseḍ %1$s? + + S tukksa n iccer-a ad tettwakkes akk tegrumma. Tzemreḍ ad ternuḍ tagrumma tamaynut melmi i tebɣiḍ. + + Kkes %1$s? Kkes @@ -892,8 +902,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ad yekkes s wudem awurman isefka n tunigin ticki tferneḍ "Ffeɣ" seg umuɣ agejdan Ad yekkes s wudem awurman isefka n tunigin ticki tferneḍ "Ffeɣ" seg umuɣ agejdan - - Amazray n tunigin Ffeɣ @@ -1240,6 +1248,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Inekcam akked wawalen uffiren ur yettwaskelsen ara ad ttwaseknen dagi. Inekcam akked wawalen uffiren ur ttwaseklasen ara i yismal-a. + + Kkes akk tisuraf Nadi inekcam @@ -1278,6 +1288,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Nɣel isem n useqdac Nɣel asmel + + Ldi asmel deg iminig Sken awal uffir diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 7fa5cc3d8..01954b6c4 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -151,13 +151,11 @@ Skann - Snarveier + Søkemotor Innstillinger for søkemotor - - Søk med - Denne gangen, søk med: + Denne gangen, søk med: Fyll inn lenke fra utklippstavlen @@ -265,8 +263,8 @@ Fjernfeilsøking via USB - - Vis søkesnarveier + + Vis søkemotorer Vis søkeforslag @@ -1232,7 +1230,7 @@ Spør om å lagre - Aldri lagre + Lagre aldri Autofyll @@ -1479,4 +1477,13 @@ OK, jeg skjønner - + + + Snarveier + + Søk med + + Denne gangen, søk med: + + Vis søkesnarveier + diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index e70e2e0b0..70b0566dd 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -148,14 +148,8 @@ Skann - - Snarvegar Innstillingar for søkjemotor - - Søk med - - Denne gong, søk med: Fyll inn lenke frå utklippstavla @@ -265,8 +259,6 @@ Fjernfeilsøking via USB - - Vis søkjesnarvegar Vis søkjeforslag @@ -581,6 +573,8 @@ Er du sikker på at du vil slette denne mappa? + + %s vil slette dei valde elementa. Sletta %1$s @@ -636,8 +630,10 @@ Sletta %1$s - + Bokmerke sletta + + Slettar valde mapper ANGRE @@ -732,6 +728,8 @@ %d fane vald Faner lagra! + + Samling lagra! Fane lagra! @@ -838,6 +836,10 @@ AVSLÅ Er du sikker på at du vil slette %1$s? + + Dersom du slettar denne fana, blir heile samlinga sletta. Du kan når som helst lage nye samlingar. + + Vil du slette %1$s? Slett @@ -1112,7 +1114,7 @@ Berre i tilpassa faner - Kryptominarar + Kryptoutvinnarar Fingerprinters Blokkert @@ -1127,7 +1129,7 @@ Blokkerer informasjonskapslar som annonsenettverk og analyseselskap brukar for å samanstille aktiviteten din på nettet på tvers av nettstadar. - Kryptominarar + Kryptoutvinnarar Hindrar vondsinna skript i å få tilgang til eininga di for å utvinne digitale valutaer. @@ -1215,7 +1217,7 @@ Spør om å lagre - Aldri lagre + Lagre aldri Autofyll @@ -1240,6 +1242,8 @@ Innloggingar og passord som ikkje er lagra vil visast her. Innloggingar og passord vil ikkje bli lagra for desse nettstadane. + + Slett alle unntak Søk innloggingar @@ -1279,6 +1283,8 @@ Kopier brukarnamn Kopier nettstad + + Opne nettstad i nettlesaren Vis passord @@ -1455,4 +1461,13 @@ OK, eg forstår det - + + + Snarvegar + + Søk med + + Denne gong, søk med: + + Vis søkjesnarvegar + diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index 19b8fd9b1..3d7507109 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -343,6 +343,8 @@ Telemetria + + Donadas tecnicas e d’utilizacion Donadas marketing @@ -362,6 +364,8 @@ Activar la sincronizacion Connexion + + S’identificar per se reconnectar Suprimir lo compte @@ -557,6 +561,8 @@ Seleccionar un dossièr Volètz vertadièrament suprimir aqueste dorsièr ? + + %s suprimirà los elements seleccionats. %1$s suprimit @@ -611,9 +617,11 @@ %1$s suprimit - + Marcapagina suprimit + + Supression dels dossièrs seleccionats ANULLAR @@ -622,6 +630,10 @@ Permissions Anar als paramètres + + Accès rapid als paramètres Recomandat @@ -804,6 +816,8 @@ REFUSAR Volètz vertadièrament suprimir %1$s ? + + Suprimir %1$s ? Suprimir @@ -1120,6 +1134,8 @@ Per ne saber mai sus Sync. Excepcions + + Suprimir totas las excepcions Recercar d’identificants diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d7167c0c5..1d2a75161 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -150,13 +150,11 @@ Skanuj - Skróty + Wyszukiwarka Ustawienia wyszukiwarki - - Szukaj w - Tym razem szukaj w: + Tym razem szukaj w: Wklej odnośnik ze schowka @@ -264,8 +262,8 @@ Narzędzia dla programistów Zdalne debugowanie przez USB - - Skróty wyszukiwania + + Wyszukiwarki Podpowiedzi wyszukiwania @@ -581,6 +579,8 @@ Wybierz folder Czy na pewno usunąć ten folder? + + %s usunie zaznaczone elementy. Usunięto folder „%1$s” @@ -635,8 +635,10 @@ Usunięto zakładkę „%1$s” - + Usunięto zakładki + + Usuwanie zaznaczonych folderów Cofnij @@ -730,6 +732,8 @@ Wybrane karty: %d Zachowano karty + + Zachowano kolekcję Zachowano kartę @@ -788,7 +792,7 @@ - Sesja przeglądania prywatnego + Sesja trybu prywatnego Usuń prywatne karty @@ -836,6 +840,10 @@ Odmów Czy na pewno usunąć „%1$s”? + + Usunięcie tej karty spowoduje usunięcie całej kolekcji. W każdej chwili można utworzyć nowe kolekcje. + + Czy usunąć „%1$s”? Usuń @@ -1237,6 +1245,8 @@ Tutaj będą wyświetlane dane logowania i hasła, które nie będą zachowywane. Dane logowania i hasła dla tych witryn nie będą zachowywane. + + Usuń wszystkie wyjątki Szukaj danych logowania @@ -1275,6 +1285,8 @@ Kopiuj nazwę użytkownika Kopiuj witrynę + + Otwórz witrynę w przeglądarce Wyświetl hasło @@ -1451,4 +1463,13 @@ OK - + + + Skróty + + Szukaj w + + Tym razem szukaj w: + + Skróty wyszukiwania + diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index ac25486d8..1a640b8cf 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -580,6 +580,8 @@ Selecionar pasta Tem a certeza que deseja eliminar esta pasta? + + %s irá excluir os itens selecionados. Eliminada %1$s @@ -634,8 +636,10 @@ %1$s eliminado - + Marcadores eliminados + + A eliminar as pastas selecionadas ANULAR @@ -729,6 +733,8 @@ %d separador selecionado Separadores guardados! + + Coleção guardada! Separador guardado! @@ -834,6 +840,10 @@ NEGAR Tem a certeza que pretende eliminar %1$s? + + A eliminação deste separador irá eliminar toda a coleção. Pode criar coleções novas a qualquer momento. + + Eliminar %1$s? Eliminar @@ -889,8 +899,6 @@ Exclui automaticamente os dados de navegação quando seleciona "Sair" no menu principal Exclui automaticamente os dados de navegação quando seleciona \"Sair\" no menu principal - - Histórico de navegação Sair @@ -1239,6 +1247,8 @@ As credenciais e palavras-passe que não estão guardadas serão mostradas aqui. As credenciais e palavras-passe não serão guardadas para estes sites. + + Eliminar todas as exceções Pesquisar credenciais @@ -1278,6 +1288,8 @@ Copiar nome de utilizador Copiar site + + Abrir site no navegador Mostrar palavra-passe diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 48e1a9269..1707c0e7e 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -148,13 +148,11 @@ Skeniraj - Bližnjice + Iskalnik Nastavitve iskalnika - - Išči z - Tokrat išči z iskalnikom: + Tokrat išči z iskalnikom: Izpolni povezavo iz odložišča @@ -262,8 +260,8 @@ Razvojna orodja Oddaljeno razhroščevanje preko USB - - Prikaži bližnjice za iskanje + + Prikaži iskalnike Prikaži predloge iskanja @@ -583,6 +581,8 @@ Izberi mapo Ali ste prepričani, da želite zbrisati to mapo? + + %s bo izbrisal izbrane predmete. Mapa %1$s izbrisana @@ -638,8 +638,10 @@ Izbrisan %1$s - + Zaznamki izbrisani + + Brisanje izbranih map RAZVELJAVI @@ -734,6 +736,8 @@ %d izbran zavihek Zavihki shranjeni! + + Zbirka shranjena! Zavihek shranjen! @@ -839,6 +843,10 @@ ZAVRNI Ali ste prepričani, da želite izbrisati %1$s? + + Če izbrišete ta zavihek, boste izbrisali celotno zbirko. Nove zbirke lahko ustvarite kadarkoli. + + Izbrišem %1$s? Izbriši @@ -1241,6 +1249,8 @@ Tu bodo prikazane prijave in gesla, ki niso shranjena. Prijave in gesla za te strani ne bodo shranjene. + + Izbriši vse izjeme Iskanje prijav @@ -1279,6 +1289,8 @@ Kopiraj uporabniško ime Kopiraj spletno mesto + + Odpri stran v brskalniku Prikaži geslo @@ -1459,4 +1471,13 @@ V redu, razumem - + + + Bližnjice + + Išči z + + Tokrat išči z iskalnikom: + + Prikaži bližnjice za iskanje + diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 322f90a73..3a0e30d4c 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -147,13 +147,11 @@ Скенирај - Пречице + Претраживач Подешавања претраживача - - Претражи са - Овај пут потражи користећи: + Овај пут потражи користећи: Убаци везу из оставе @@ -262,8 +260,8 @@ Алати за програмере Удаљено отклањање грешака преко USB-а - - Пречице за претрагу + + Прикажи претраживаче Предлози претраге @@ -576,6 +574,8 @@ Изабери фасциклу Да ли сте сигурни да желите да избришете ову фасциклу? + + %s ће обрисати одабране ставке. %1$s избрисано @@ -630,8 +630,10 @@ Обрисано %1$s - + Обележивачи су избрисани + + Брисање одабраних фасцикли ОПОЗОВИ @@ -725,6 +727,8 @@ %d језичак изабран Језичци сачувани! + + Збирка је сачувана! Језичак сачуван! @@ -830,6 +834,10 @@ ОДБИЈ Да ли сте сигурни да желите обрисати збирку %1$s? + + Брисањем овог језичка обрисаћете целу једну збирку. Можете да направите нову збирку било кад. + + Обрисати %1$s? Обриши @@ -884,8 +892,6 @@ Самостално брише податке прегледања када изаберете „Изађи“ у главном менију Самостално брише податке прегледања када изаберете \"Изађи\" у главном менију - - Историјат прегледања Изађи @@ -1236,6 +1242,8 @@ Овде ће бити приказане пријаве и лозинке које нису сачуване. Пријаве и лозинке неће бити сачуване за ове странице. + + Обрисати све изузетке Претражи пријаве @@ -1274,6 +1282,8 @@ Копирај корисничко Копирај страницу + + Отвори страницу у прегледачу Прикажи лозинку @@ -1450,4 +1460,13 @@ Важи, разумем - + + + Пречице + + Претражи са + + Овај пут потражи користећи: + + Пречице за претрагу + diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 9304c25b2..60dc9e5a9 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -151,14 +151,11 @@ Skanna - Genvägar + Sökmotor Inställningar för sökmotor - - Sök med - - Denna gång, sök med: + Denna gång, sök med: Fyll i länk från urklipp @@ -266,8 +263,8 @@ Utvecklarverktyg Fjärrfelsökning via USB - - Visa sökgenvägar + + Visa sökmotorer Visa sökförslag @@ -1473,4 +1470,14 @@ Ok, jag förstår - + + + Genvägar + + Sök med + + + Denna gång, sök med: + + Visa sökgenvägar + diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index da34254b5..bfef1a9e8 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -582,6 +582,8 @@ సంచయపు ఎంపిక మీరు నిజంగానే ఈ సంచయాన్ని తొలగించాలనుకుంటున్నారా? + + ఎంచుకున్న అంశాలను %s తొలగిస్తుంది. %1$s తొలగించబడింది @@ -638,9 +640,11 @@ %1$s తొలగించబడింది - + ఇష్టాంశాలు తొలగించబడ్డాయి + + ఎంచుకున్న సంచయాలను తొలగిస్తూంది చర్య రద్దు @@ -736,6 +740,8 @@ %d ట్యాబు ఎంచుకున్నారు ట్యాబులు భద్రమయ్యాయి! + + సేకరణ భద్రమయ్యింది! ట్యాబు భద్రమయింది! @@ -840,6 +846,10 @@ తిరస్కరించు మీరు నిజంగానే %1$s‌ను తొలగించాలనుకుంటున్నారా? + + ఈ ట్యాబును తొలగిస్తే మొత్తం సేకరణ పోతుంది. కొత్త సేకరణలను మీరు ఎప్పుడైనా సృష్టించుకోవచ్చు. + + %1$s‌ని తొలగించాలా? తొలగించు @@ -1250,6 +1260,8 @@ భద్రపరచని ప్రవేశాలు, సంకేతపదాలు ఇక్కడ కనిపిస్తాయి. ఈ సైట్ల ప్రవేశాలు, సంకేతపదాలు భద్రపరచబడవు. + + మినహాయింపులన్నీ తొలగించు ప్రవేశాలను వెతకండి @@ -1289,6 +1301,8 @@ వాడుకరి పేరుని కాపీచెయ్యి సైటును కాపీచెయ్యి + + సైటును విహారిణిలో తెరువు సంకేతపదాన్ని చూపించు diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index e00860230..2752cf6ed 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -150,14 +150,11 @@ Сканувати - Ярлики - + Засіб пошуку Налаштування пошукових засобів - - Шукати з - Цього разу шукати з: + Цього разу шукати з: Заповнити посилання з буфера обміну @@ -268,8 +265,8 @@ Віддалене зневадження через USB - - Посилання на пошукові засоби + + Показати засоби пошуку Показувати пошукові пропозиції @@ -586,6 +583,8 @@ Обрати теку Ви впевнені, що хочете видалити цю теку? + + %s видалить вибрані елементи. %1$s видалено @@ -641,8 +640,10 @@ %1$s видалено - + Закладки видалено + + Видалення вибраних тек ВІДНОВИТИ @@ -736,6 +737,8 @@ Вибрано %d вкладку Вкладки збережено! + + Збірку збережено! Вкладка збережена! @@ -842,6 +845,10 @@ ЗАБОРОНИТИ Ви дійсно хочете видалити %1$s? + + Видалення цієї вкладки видалить всю збірку. Ви можете створити нові збірки будь-коли. + + Видалити %1$s? Видалити @@ -1246,6 +1253,8 @@ Не збережені паролі з’являтимуться тут. Паролі для цих сайтів не зберігатимуться. + + Видалити всі винятки Шукати паролі @@ -1285,6 +1294,8 @@ Копіювати ім’я користувача Копіювати сайт + + Відкрити сайт у браузері Показати пароль @@ -1460,4 +1471,14 @@ Гаразд, зрозуміло - + + + Ярлики + + + Шукати з + + Цього разу шукати з: + + Посилання на пошукові засоби + From 6530a45eb9b2bc8b60497d47600b7b233762dc6d Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Thu, 23 Jul 2020 12:12:22 -0400 Subject: [PATCH 03/47] For issue #11676: Features phone that doesn't a site permission exception shouldn't be shown (#12855) exception shouldn't be shown --- .../settings/quicksettings/ext/PhoneFeatureExt.kt | 10 +++++++++- .../quicksettings/ext/PhoneFeatureExtKtTest.kt | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExt.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExt.kt index 0958209f8..4169e1eb6 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExt.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExt.kt @@ -17,7 +17,15 @@ import org.mozilla.fenix.utils.Settings fun PhoneFeature.shouldBeVisible( sitePermissions: SitePermissions?, settings: Settings -) = getStatus(sitePermissions, settings) != SitePermissions.Status.NO_DECISION +): Boolean { + // We have to check if the site have a site permission exception, + // if it doesn't the feature shouldn't be visible + return if (sitePermissions == null) { + false + } else { + getStatus(sitePermissions, settings) != SitePermissions.Status.NO_DECISION + } +} /** * Common [PhoneFeature] extensions used for **quicksettings**. diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExtKtTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExtKtTest.kt index 834b88431..73d80f8ad 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExtKtTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/ext/PhoneFeatureExtKtTest.kt @@ -27,6 +27,8 @@ class PhoneFeatureExtKtTest { assertFalse(PhoneFeature.CAMERA.shouldBeVisible(noDecisionForPermission, mockk())) assertTrue(PhoneFeature.CAMERA.shouldBeVisible(userAllowedPermission, mockk())) assertTrue(PhoneFeature.CAMERA.shouldBeVisible(userBlockedPermission, mockk())) + // The site doesn't have a site permission exception + assertFalse(PhoneFeature.CAMERA.shouldBeVisible(null, mockk())) } @Test From 4e9fc88f6394d2becbe05715a59323512591abda Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 23 Jul 2020 14:33:56 +0000 Subject: [PATCH 04/47] Update Android Components version to 52.0.20200723130248. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 448860de0..9521492df 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "52.0.20200722023149" + const val VERSION = "52.0.20200723130248" } From 0d77f761e93cf7bb89845099bafd0d987efb86cf Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Thu, 23 Jul 2020 11:16:11 -0700 Subject: [PATCH 05/47] Test sync adapter (#12810) --- .../mozilla/fenix/sync/SyncedTabsAdapter.kt | 41 ++++--- .../mozilla/fenix/sync/SyncedTabsLayout.kt | 34 ++---- .../fenix/sync/SyncedTabsAdapterTest.kt | 105 ++++++++++++++++++ .../fenix/sync/SyncedTabsLayoutTest.kt | 29 ++++- 4 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/sync/SyncedTabsAdapterTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt index d45c9e8c7..69ace066f 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsAdapter.kt @@ -8,16 +8,15 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter -import mozilla.components.concept.sync.Device as SyncDevice -import mozilla.components.browser.storage.sync.Tab as SyncTab +import mozilla.components.browser.storage.sync.SyncedDeviceTabs import org.mozilla.fenix.sync.SyncedTabsViewHolder.DeviceViewHolder import org.mozilla.fenix.sync.SyncedTabsViewHolder.TabViewHolder +import mozilla.components.browser.storage.sync.Tab as SyncTab +import mozilla.components.concept.sync.Device as SyncDevice class SyncedTabsAdapter( private val listener: (SyncTab) -> Unit -) : ListAdapter( - DiffCallback -) { +) : ListAdapter(DiffCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SyncedTabsViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(viewType, parent, false) @@ -30,23 +29,35 @@ class SyncedTabsAdapter( } override fun onBindViewHolder(holder: SyncedTabsViewHolder, position: Int) { - val item = when (holder) { - is DeviceViewHolder -> getItem(position) as AdapterItem.Device - is TabViewHolder -> getItem(position) as AdapterItem.Tab - } - holder.bind(item, listener) + holder.bind(getItem(position), listener) } - override fun getItemViewType(position: Int): Int { - return when (getItem(position)) { - is AdapterItem.Device -> DeviceViewHolder.LAYOUT_ID - is AdapterItem.Tab -> TabViewHolder.LAYOUT_ID + override fun getItemViewType(position: Int) = when (getItem(position)) { + is AdapterItem.Device -> DeviceViewHolder.LAYOUT_ID + is AdapterItem.Tab -> TabViewHolder.LAYOUT_ID + } + + fun updateData(syncedTabs: List) { + val allDeviceTabs = mutableListOf() + + syncedTabs.forEach { (device, tabs) -> + if (tabs.isNotEmpty()) { + allDeviceTabs.add(AdapterItem.Device(device)) + tabs.mapTo(allDeviceTabs) { AdapterItem.Tab(it) } + } } + + submitList(allDeviceTabs) } private object DiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) = - areContentsTheSame(oldItem, newItem) + when (oldItem) { + is AdapterItem.Device -> + newItem is AdapterItem.Device && oldItem.device.id == newItem.device.id + is AdapterItem.Tab -> + oldItem == newItem + } @Suppress("DiffUtilEquals") override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) = diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt index c5bbf4d4e..0889ccb50 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt @@ -10,10 +10,10 @@ import android.view.View import android.widget.FrameLayout import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.component_sync_tabs.view.* -import kotlinx.coroutines.launch import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import mozilla.components.browser.storage.sync.SyncedDeviceTabs import mozilla.components.feature.syncedtabs.view.SyncedTabsView import org.mozilla.fenix.R @@ -43,15 +43,7 @@ class SyncedTabsLayout @JvmOverloads constructor( // We may still be displaying a "loading" spinner, hide it. stopLoading() - val stringResId = when (error) { - SyncedTabsView.ErrorType.MULTIPLE_DEVICES_UNAVAILABLE -> R.string.synced_tabs_connect_another_device - SyncedTabsView.ErrorType.SYNC_ENGINE_UNAVAILABLE -> R.string.synced_tabs_enable_tab_syncing - SyncedTabsView.ErrorType.SYNC_UNAVAILABLE -> R.string.synced_tabs_connect_to_sync_account - SyncedTabsView.ErrorType.SYNC_NEEDS_REAUTHENTICATION -> R.string.synced_tabs_reauth - SyncedTabsView.ErrorType.NO_TABS_AVAILABLE -> R.string.synced_tabs_no_tabs - } - - sync_tabs_status.text = context.getText(stringResId) + sync_tabs_status.text = context.getText(stringResourceForError(error)) synced_tabs_list.visibility = View.GONE sync_tabs_status.visibility = View.VISIBLE @@ -65,19 +57,7 @@ class SyncedTabsLayout @JvmOverloads constructor( synced_tabs_list.visibility = View.VISIBLE sync_tabs_status.visibility = View.GONE - val allDeviceTabs = emptyList().toMutableList() - - syncedTabs.forEach { (device, tabs) -> - if (tabs.isEmpty()) { - return@forEach - } - - val deviceTabs = tabs.map { SyncedTabsAdapter.AdapterItem.Tab(it) } - - allDeviceTabs += listOf(SyncedTabsAdapter.AdapterItem.Device(device)) + deviceTabs - } - - adapter.submitList(allDeviceTabs) + adapter.updateData(syncedTabs) } } @@ -110,5 +90,13 @@ class SyncedTabsLayout @JvmOverloads constructor( SyncedTabsView.ErrorType.MULTIPLE_DEVICES_UNAVAILABLE, SyncedTabsView.ErrorType.NO_TABS_AVAILABLE -> true } + + internal fun stringResourceForError(error: SyncedTabsView.ErrorType) = when (error) { + SyncedTabsView.ErrorType.MULTIPLE_DEVICES_UNAVAILABLE -> R.string.synced_tabs_connect_another_device + SyncedTabsView.ErrorType.SYNC_ENGINE_UNAVAILABLE -> R.string.synced_tabs_enable_tab_syncing + SyncedTabsView.ErrorType.SYNC_UNAVAILABLE -> R.string.synced_tabs_connect_to_sync_account + SyncedTabsView.ErrorType.SYNC_NEEDS_REAUTHENTICATION -> R.string.synced_tabs_reauth + SyncedTabsView.ErrorType.NO_TABS_AVAILABLE -> R.string.synced_tabs_no_tabs + } } } diff --git a/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsAdapterTest.kt b/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsAdapterTest.kt new file mode 100644 index 000000000..e22bbb181 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsAdapterTest.kt @@ -0,0 +1,105 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.sync + +import android.widget.FrameLayout +import io.mockk.every +import io.mockk.mockk +import mozilla.components.browser.storage.sync.SyncedDeviceTabs +import mozilla.components.browser.storage.sync.Tab +import mozilla.components.browser.storage.sync.TabEntry +import mozilla.components.concept.sync.DeviceType +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class SyncedTabsAdapterTest { + + private lateinit var listener: (Tab) -> Unit + private lateinit var adapter: SyncedTabsAdapter + + private val oneTabDevice = SyncedDeviceTabs( + device = mockk { + every { displayName } returns "Charcoal" + every { deviceType } returns DeviceType.DESKTOP + }, + tabs = listOf(Tab( + history = listOf(TabEntry( + title = "Mozilla", + url = "https://mozilla.org", + iconUrl = null + )), + active = 0, + lastUsed = 0L + )) + ) + + private val threeTabDevice = SyncedDeviceTabs( + device = mockk { + every { displayName } returns "Emerald" + every { deviceType } returns DeviceType.MOBILE + }, + tabs = listOf( + Tab( + history = listOf(TabEntry( + title = "Mozilla", + url = "https://mozilla.org", + iconUrl = null + )), + active = 0, + lastUsed = 0L + ), + Tab( + history = listOf(TabEntry( + title = "Firefox", + url = "https://firefox.com", + iconUrl = null + )), + active = 0, + lastUsed = 0L + ) + ) + ) + + @Before + fun setup() { + listener = mockk(relaxed = true) + adapter = SyncedTabsAdapter(listener) + } + + @Test + fun `updateData() adds items for each device and tab`() { + assertEquals(0, adapter.itemCount) + + adapter.updateData(listOf( + oneTabDevice, + threeTabDevice + )) + + assertEquals(5, adapter.itemCount) + assertEquals(SyncedTabsViewHolder.DeviceViewHolder.LAYOUT_ID, adapter.getItemViewType(0)) + assertEquals(SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID, adapter.getItemViewType(1)) + assertEquals(SyncedTabsViewHolder.DeviceViewHolder.LAYOUT_ID, adapter.getItemViewType(2)) + assertEquals(SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID, adapter.getItemViewType(3)) + assertEquals(SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID, adapter.getItemViewType(4)) + } + + @Test + fun `adapter can create and bind viewholders for SyncedDeviceTabs`() { + val parent = FrameLayout(testContext) + adapter.updateData(listOf(oneTabDevice)) + + val deviceHolder = adapter.createViewHolder(parent, SyncedTabsViewHolder.DeviceViewHolder.LAYOUT_ID) + val tabHolder = adapter.createViewHolder(parent, SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID) + + // Should not throw + adapter.bindViewHolder(deviceHolder, 0) + adapter.bindViewHolder(tabHolder, 1) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsLayoutTest.kt b/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsLayoutTest.kt index 7b69743b9..9805c4445 100644 --- a/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsLayoutTest.kt +++ b/app/src/test/java/org/mozilla/fenix/sync/SyncedTabsLayoutTest.kt @@ -5,11 +5,14 @@ package org.mozilla.fenix.sync import mozilla.components.feature.syncedtabs.view.SyncedTabsView.ErrorType -import org.junit.Assert.assertTrue +import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Test +import org.mozilla.fenix.R class SyncedTabsLayoutTest { + @Test fun `pull to refresh state`() { assertTrue(SyncedTabsLayout.pullToRefreshEnableState(ErrorType.MULTIPLE_DEVICES_UNAVAILABLE)) @@ -18,4 +21,28 @@ class SyncedTabsLayoutTest { assertFalse(SyncedTabsLayout.pullToRefreshEnableState(ErrorType.SYNC_NEEDS_REAUTHENTICATION)) assertFalse(SyncedTabsLayout.pullToRefreshEnableState(ErrorType.SYNC_UNAVAILABLE)) } + + @Test + fun `string resource for error`() { + assertEquals( + R.string.synced_tabs_connect_another_device, + SyncedTabsLayout.stringResourceForError(ErrorType.MULTIPLE_DEVICES_UNAVAILABLE) + ) + assertEquals( + R.string.synced_tabs_enable_tab_syncing, + SyncedTabsLayout.stringResourceForError(ErrorType.SYNC_ENGINE_UNAVAILABLE) + ) + assertEquals( + R.string.synced_tabs_connect_to_sync_account, + SyncedTabsLayout.stringResourceForError(ErrorType.SYNC_UNAVAILABLE) + ) + assertEquals( + R.string.synced_tabs_reauth, + SyncedTabsLayout.stringResourceForError(ErrorType.SYNC_NEEDS_REAUTHENTICATION) + ) + assertEquals( + R.string.synced_tabs_no_tabs, + SyncedTabsLayout.stringResourceForError(ErrorType.NO_TABS_AVAILABLE) + ) + } } From 9af167ba0a8f91b0430d793c24198ed336127368 Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Thu, 23 Jul 2020 11:17:52 -0700 Subject: [PATCH 06/47] Add tests for some classes in home/browser (#12837) --- .../fenix/browser/UriOpenedObserver.kt | 13 +- .../fenix/home/tips/ButtonTipViewHolder.kt | 76 ++++++----- .../fenix/browser/UriOpenedObserverTest.kt | 23 +++- .../DefaultReaderModeControllerTest.kt | 41 ++++++ .../home/tips/ButtonTipViewHolderTest.kt | 126 ++++++++++++++++++ 5 files changed, 234 insertions(+), 45 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/home/tips/ButtonTipViewHolderTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt b/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt index 213bec6a9..3c42b1f1e 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt @@ -12,6 +12,7 @@ import mozilla.components.browser.session.SessionManager import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.metrics +import org.mozilla.fenix.ext.sessionsOfType import org.mozilla.fenix.ext.settings import org.mozilla.fenix.search.telemetry.ads.AdsTelemetry import org.mozilla.fenix.utils.Settings @@ -44,25 +45,29 @@ class UriOpenedObserver( session.register(singleSessionObserver, owner) } + private fun saveOpenTabsCount() { + settings.setOpenTabsCount(sessionManager.sessionsOfType(private = false).count()) + } + override fun onAllSessionsRemoved() { - settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) + saveOpenTabsCount() sessionManager.sessions.forEach { it.unregister(singleSessionObserver) } } override fun onSessionAdded(session: Session) { - settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) + saveOpenTabsCount() session.register(singleSessionObserver, owner) } override fun onSessionRemoved(session: Session) { - settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) + saveOpenTabsCount() session.unregister(singleSessionObserver) } override fun onSessionsRestored() { - settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) + saveOpenTabsCount() sessionManager.sessions.forEach { it.register(singleSessionObserver, owner) } diff --git a/app/src/main/java/org/mozilla/fenix/home/tips/ButtonTipViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/tips/ButtonTipViewHolder.kt index 1711ff071..17b31b35b 100644 --- a/app/src/main/java/org/mozilla/fenix/home/tips/ButtonTipViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/tips/ButtonTipViewHolder.kt @@ -1,23 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.home.tips import android.view.View -import androidx.recyclerview.widget.RecyclerView -import kotlinx.android.synthetic.main.button_tip_item.view.* +import androidx.core.view.isVisible +import kotlinx.android.synthetic.main.button_tip_item.* import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.tips.Tip import org.mozilla.fenix.components.tips.TipType import org.mozilla.fenix.ext.addUnderline import org.mozilla.fenix.ext.components -import org.mozilla.fenix.ext.settings import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor +import org.mozilla.fenix.utils.Settings +import org.mozilla.fenix.utils.view.ViewHolder class ButtonTipViewHolder( - val view: View, - val interactor: SessionControlInteractor -) : RecyclerView.ViewHolder(view) { + view: View, + private val interactor: SessionControlInteractor, + private val metrics: MetricController = view.context.components.analytics.metrics, + private val settings: Settings = view.context.components.settings +) : ViewHolder(view) { + var tip: Tip? = null fun bind(tip: Tip) { @@ -25,44 +34,39 @@ class ButtonTipViewHolder( this.tip = tip - view.apply { - context.components.analytics.metrics.track(Event.TipDisplayed(tip.identifier)) + metrics.track(Event.TipDisplayed(tip.identifier)) - tip_header_text.text = tip.title - tip_description_text.text = tip.description - tip_button.text = tip.type.text + tip_header_text.text = tip.title + tip_description_text.text = tip.description + tip_button.text = tip.type.text - if (tip.learnMoreURL == null) { - tip_learn_more.visibility = View.GONE - } else { - tip_learn_more.addUnderline() + tip_learn_more.isVisible = tip.learnMoreURL != null + if (tip.learnMoreURL != null) { + tip_learn_more.addUnderline() - tip_learn_more.setOnClickListener { - (context as HomeActivity).openToBrowserAndLoad( - searchTermOrURL = tip.learnMoreURL, - newTab = true, - from = BrowserDirection.FromHome - ) - } - } - - tip_button.setOnClickListener { - tip.type.action.invoke() - context.components.analytics.metrics.track( - Event.TipPressed(tip.identifier) + tip_learn_more.setOnClickListener { + (itemView.context as HomeActivity).openToBrowserAndLoad( + searchTermOrURL = tip.learnMoreURL, + newTab = true, + from = BrowserDirection.FromHome ) } + } - tip_close.setOnClickListener { - context.components.analytics.metrics.track(Event.TipClosed(tip.identifier)) + tip_button.setOnClickListener { + tip.type.action.invoke() + metrics.track(Event.TipPressed(tip.identifier)) + } - context.settings().preferences - .edit() - .putBoolean(tip.identifier, false) - .apply() + tip_close.setOnClickListener { + metrics.track(Event.TipClosed(tip.identifier)) - interactor.onCloseTip(tip) - } + settings.preferences + .edit() + .putBoolean(tip.identifier, false) + .apply() + + interactor.onCloseTip(tip) } } diff --git a/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt b/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt index 7822da7b0..b57b29ac8 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt @@ -5,7 +5,9 @@ package org.mozilla.fenix.browser import androidx.lifecycle.LifecycleOwner +import io.mockk.MockKAnnotations import io.mockk.every +import io.mockk.impl.annotations.MockK import io.mockk.mockk import io.mockk.verify import mozilla.components.browser.session.Session @@ -18,15 +20,16 @@ import org.mozilla.fenix.utils.Settings class UriOpenedObserverTest { - private val settings: Settings = mockk(relaxed = true) - private val owner: LifecycleOwner = mockk(relaxed = true) - private val sessionManager: SessionManager = mockk(relaxed = true) - private val metrics: MetricController = mockk() - private val ads: AdsTelemetry = mockk() + @MockK(relaxed = true) private lateinit var settings: Settings + @MockK(relaxed = true) private lateinit var owner: LifecycleOwner + @MockK(relaxed = true) private lateinit var sessionManager: SessionManager + @MockK private lateinit var metrics: MetricController + @MockK private lateinit var ads: AdsTelemetry private lateinit var observer: UriOpenedObserver @Before fun setup() { + MockKAnnotations.init(this) observer = UriOpenedObserver(settings, owner, sessionManager, metrics, ads) } @@ -37,6 +40,14 @@ class UriOpenedObserverTest { @Test fun `registers single session observer`() { + every { sessionManager.sessions } returns listOf( + mockk { + every { private } returns false + }, + mockk { + every { private } returns true + } + ) val session: Session = mockk(relaxed = true) observer.onSessionAdded(session) @@ -47,6 +58,8 @@ class UriOpenedObserverTest { observer.onSessionRemoved(session) verify { session.unregister(observer.singleSessionObserver) } + + verify { settings.setOpenTabsCount(1) } } @Test diff --git a/app/src/test/java/org/mozilla/fenix/browser/readermode/DefaultReaderModeControllerTest.kt b/app/src/test/java/org/mozilla/fenix/browser/readermode/DefaultReaderModeControllerTest.kt index 085bae069..56a48b4c1 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/readermode/DefaultReaderModeControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/readermode/DefaultReaderModeControllerTest.kt @@ -4,12 +4,16 @@ package org.mozilla.fenix.browser.readermode +import android.content.res.ColorStateList import android.view.View +import android.widget.Button +import android.widget.RadioButton import io.mockk.Called import io.mockk.every import io.mockk.mockk import io.mockk.spyk import io.mockk.verify +import io.mockk.verifyAll import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore @@ -19,6 +23,7 @@ import mozilla.components.support.test.robolectric.testContext 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) @@ -77,4 +82,40 @@ class DefaultReaderModeControllerTest { verify { readerViewFeature.showControls() } verify { readerViewControlsBar wasNot Called } } + + @Test + fun testShowControlsPrivateTab() { + val controller = DefaultReaderModeController( + featureWrapper, + readerViewControlsBar, + isPrivate = true + ) + + val decrease = mockk