[fenix] For https://github.com/mozilla-mobile/fenix/issues/24319 - Migrate PrivateBrowsingDescriptionViewHolder to Compose

pull/600/head
Gabriel Luong 3 years ago committed by mergify[bot]
parent 7320080c11
commit 7f73bfcd90

@ -104,6 +104,7 @@ class CrashReportingTest {
} }
} }
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24508")
@SmokeTest @SmokeTest
@Test @Test
fun privateBrowsingUseAppWhileTabIsCrashedTest() { fun privateBrowsingUseAppWhileTabIsCrashedTest() {

@ -56,6 +56,7 @@ class HomeScreenTest {
} }
} }
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24508")
@Test @Test
fun privateModeScreenItemsTest() { fun privateModeScreenItemsTest() {
homeScreen { }.dismissOnboarding() homeScreen { }.dismissOnboarding()

@ -948,6 +948,7 @@ class SmokeTest {
} }
} }
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24508")
@Test @Test
fun addPrivateBrowsingShortcutTest() { fun addPrivateBrowsingShortcutTest() {
homeScreen { homeScreen {

@ -333,6 +333,7 @@ class TabbedBrowsingTest {
} }
} }
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24508")
@Test @Test
fun verifyContextMenuShortcuts() { fun verifyContextMenuShortcuts() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)

@ -375,7 +375,7 @@ class HomeScreenRobot {
} }
fun openCommonMythsLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun openCommonMythsLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
onView(withId(R.id.private_session_common_myths)) onView(withText(R.string.private_browsing_common_myths))
.perform(click()) .perform(click())
BrowserRobot().interact() BrowserRobot().interact()
@ -629,7 +629,7 @@ private fun assertTakePlacementBottomRadioButton() {
} }
private fun assertPrivateSessionMessage() = private fun assertPrivateSessionMessage() =
onView(withId(R.id.private_session_description)) onView(withText(R.string.private_browsing_common_myths))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun collectionTitle(title: String) = private fun collectionTitle(title: String) =

@ -216,7 +216,12 @@ class SessionControlAdapter(
when (viewType) { when (viewType) {
CustomizeHomeButtonViewHolder.LAYOUT_ID -> return CustomizeHomeButtonViewHolder( CustomizeHomeButtonViewHolder.LAYOUT_ID -> return CustomizeHomeButtonViewHolder(
composeView = ComposeView(parent.context), composeView = ComposeView(parent.context),
viewLifecycleOwner, viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor
)
PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> return PrivateBrowsingDescriptionViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor interactor = interactor
) )
PocketStoriesViewHolder.LAYOUT_ID -> return PocketStoriesViewHolder( PocketStoriesViewHolder.LAYOUT_ID -> return PocketStoriesViewHolder(
@ -236,18 +241,18 @@ class SessionControlAdapter(
) )
RecentBookmarksViewHolder.LAYOUT_ID -> return RecentBookmarksViewHolder( RecentBookmarksViewHolder.LAYOUT_ID -> return RecentBookmarksViewHolder(
composeView = ComposeView(parent.context), composeView = ComposeView(parent.context),
viewLifecycleOwner, viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor, interactor = interactor,
metrics = components.analytics.metrics metrics = components.analytics.metrics
) )
RecentTabViewHolder.LAYOUT_ID -> return RecentTabViewHolder( RecentTabViewHolder.LAYOUT_ID -> return RecentTabViewHolder(
composeView = ComposeView(parent.context), composeView = ComposeView(parent.context),
viewLifecycleOwner, viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor interactor = interactor
) )
RecentlyVisitedViewHolder.LAYOUT_ID -> return RecentlyVisitedViewHolder( RecentlyVisitedViewHolder.LAYOUT_ID -> return RecentlyVisitedViewHolder(
composeView = ComposeView(parent.context), composeView = ComposeView(parent.context),
viewLifecycleOwner, viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor, interactor = interactor,
metrics = components.analytics.metrics metrics = components.analytics.metrics
) )
@ -272,10 +277,6 @@ class SessionControlAdapter(
return when (viewType) { return when (viewType) {
TopPlaceholderViewHolder.LAYOUT_ID -> TopPlaceholderViewHolder(view) TopPlaceholderViewHolder.LAYOUT_ID -> TopPlaceholderViewHolder(view)
TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(view, viewLifecycleOwner, interactor) TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(view, viewLifecycleOwner, interactor)
PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(
view,
interactor
)
NoCollectionsMessageViewHolder.LAYOUT_ID -> NoCollectionsMessageViewHolder.LAYOUT_ID ->
NoCollectionsMessageViewHolder( NoCollectionsMessageViewHolder(
view, view,
@ -319,6 +320,7 @@ class SessionControlAdapter(
is RecentBookmarksHeaderViewHolder, is RecentBookmarksHeaderViewHolder,
is RecentTabViewHolder, is RecentTabViewHolder,
is RecentTabsHeaderViewHolder, is RecentTabsHeaderViewHolder,
is PrivateBrowsingDescriptionViewHolder,
is PocketCategoriesViewHolder, is PocketCategoriesViewHolder,
is PocketRecommendationsHeaderViewHolder, is PocketRecommendationsHeaderViewHolder,
is PocketStoriesViewHolder -> { is PocketStoriesViewHolder -> {

@ -4,36 +4,122 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.LifecycleOwner
import mozilla.components.ui.colors.PhotonColors
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.PrivateBrowsingDescriptionBinding import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.home.sessioncontrol.TabSessionInteractor import org.mozilla.fenix.home.sessioncontrol.TabSessionInteractor
import org.mozilla.fenix.theme.FirefoxTheme
/**
* View holder for a private browsing description.
*
* @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
* @param viewLifecycleOwner [LifecycleOwner] life cycle owner for the view.
* @param interactor [TabSessionInteractor] which will have delegated to all user interactions.
*/
class PrivateBrowsingDescriptionViewHolder( class PrivateBrowsingDescriptionViewHolder(
view: View, composeView: ComposeView,
private val interactor: TabSessionInteractor viewLifecycleOwner: LifecycleOwner,
) : RecyclerView.ViewHolder(view) { val interactor: TabSessionInteractor,
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
init { init {
val resources = view.resources val horizontalPadding =
val appName = resources.getString(R.string.app_name) composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
val binding = PrivateBrowsingDescriptionBinding.bind(view) composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
binding.privateSessionDescription.text = resources.getString( }
R.string.private_browsing_placeholder_description_2, appName
@Composable
override fun Content() {
PrivateBrowsingDescription(
onLearnMoreClick = interactor::onPrivateBrowsingLearnMoreClicked
) )
with(binding.privateSessionCommonMyths) {
movementMethod = LinkMovementMethod.getInstance()
addUnderline()
setOnClickListener {
interactor.onPrivateBrowsingLearnMoreClicked()
} }
companion object {
val LAYOUT_ID = View.generateViewId()
} }
} }
companion object { /**
const val LAYOUT_ID = R.layout.private_browsing_description * Private browsing mode description.
*
* @param onLearnMoreClick Invoked when the user clicks on the learn more link.
*/
@Composable
fun PrivateBrowsingDescription(
onLearnMoreClick: () -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val color = PhotonColors.LightGrey05 // Equivalent to fx_mobile_private_text_color_primary.
Column(
modifier = Modifier.padding(horizontal = 4.dp)
) {
Text(
text = stringResource(
R.string.private_browsing_placeholder_description_2,
stringResource(R.string.app_name)
),
modifier = Modifier.padding(top = 4.dp),
color = color,
fontSize = 14.sp,
lineHeight = 20.sp
)
// The text is wrapped in a box to increase the tap area.
Box(
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
.clickable(
interactionSource = interactionSource,
indication = null,
onClickLabel = stringResource(R.string.link_text_view_type_announcement),
onClick = onLearnMoreClick,
)
) {
Text(
text = stringResource(R.string.private_browsing_common_myths),
modifier = Modifier.padding(top = 10.dp),
style = TextStyle(
color = color,
fontSize = 14.sp,
textDecoration = TextDecoration.Underline,
textDirection = TextDirection.Content
)
)
}
}
}
@Composable
@Preview
private fun PrivateBrowsingDescriptionPreview() {
FirefoxTheme {
PrivateBrowsingDescription(
onLearnMoreClick = {}
)
} }
} }

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/private_session_description_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/home_item_horizontal_margin"
android:importantForAccessibility="no"
android:orientation="vertical">
<TextView
android:id="@+id/private_session_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="none"
android:lineSpacingExtra="6dp"
android:paddingHorizontal="4dp"
android:paddingTop="4dp"
android:scrollHorizontally="false"
android:textAlignment="viewStart"
android:textColor="?attr/textPrimary"
android:textDirection="locale"
android:textSize="14sp"
tools:text="@string/private_browsing_placeholder_description_2" />
<org.mozilla.fenix.utils.LinkTextView
android:id="@+id/private_session_common_myths"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="none"
android:gravity="center_vertical"
android:lineSpacingExtra="6dp"
android:paddingHorizontal="4dp"
android:paddingTop="10dp"
android:paddingBottom="19dp"
android:scrollHorizontally="false"
android:text="@string/private_browsing_common_myths"
android:textColor="?attr/textPrimary"
android:textSize="14sp" />
</LinearLayout>

@ -1,37 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.view.LayoutInflater
import io.mockk.mockk
import io.mockk.verify
import mozilla.components.support.test.robolectric.testContext
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.databinding.PrivateBrowsingDescriptionBinding
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.TabSessionInteractor
@RunWith(FenixRobolectricTestRunner::class)
class PrivateBrowsingDescriptionViewHolderTest {
private lateinit var binding: PrivateBrowsingDescriptionBinding
private lateinit var interactor: TabSessionInteractor
@Before
fun setup() {
binding = PrivateBrowsingDescriptionBinding.inflate(LayoutInflater.from(testContext))
interactor = mockk(relaxed = true)
}
@Test
fun `call interactor on click`() {
PrivateBrowsingDescriptionViewHolder(binding.root, interactor)
binding.privateSessionCommonMyths.performClick()
verify { interactor.onPrivateBrowsingLearnMoreClicked() }
}
}
Loading…
Cancel
Save