For #23968 - Migrate homescreen recent tabs to compose

For #23968 - Migrate homescreen recent tabs to compose
upstream-sync
sarah541 2 years ago committed by mergify[bot]
parent ce7d2d1962
commit 3b39b4668f

@ -5,8 +5,8 @@
"exposureDescription": "",
"variables": {
"message-location": {
"description": "Where is the message to be put.",
"type": "string"
"type": "string",
"description": "Where is the message to be put."
}
}
},
@ -16,8 +16,8 @@
"exposureDescription": "",
"variables": {
"sections-enabled": {
"description": "This property provides a lookup table of whether or not the given section should be enabled. If the section is enabled, it should be toggleable in the settings screen, and on by default.",
"type": "json"
"type": "json",
"description": "This property provides a lookup table of whether or not the given section should be enabled. If the section is enabled, it should be toggleable in the settings screen, and on by default."
}
}
},
@ -54,16 +54,16 @@
"exposureDescription": "",
"variables": {
"settings-icon": {
"description": "The drawable displayed in the app menu for Settings",
"type": "string"
"type": "string",
"description": "The drawable displayed in the app menu for Settings"
},
"settings-punctuation": {
"description": "The emoji displayed in the Settings screen title.",
"type": "string"
"type": "string",
"description": "The emoji displayed in the Settings screen title."
},
"settings-title": {
"description": "The title of displayed in the Settings screen and app menu.",
"type": "string"
"type": "string",
"description": "The title of displayed in the Settings screen and app menu."
}
}
},
@ -73,8 +73,8 @@
"exposureDescription": "",
"variables": {
"enabled": {
"description": "If true, the feature shows up on the homescreen and on the new tab screen.",
"type": "boolean"
"type": "boolean",
"description": "If true, the feature shows up on the homescreen and on the new tab screen."
}
}
}

@ -4,7 +4,7 @@
package org.mozilla.fenix.compose.home
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentHeight
@ -18,6 +18,7 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.SectionHeader
@ -26,22 +27,21 @@ import org.mozilla.fenix.theme.FirefoxTheme
/**
* Homepage header.
*
* @param text The header string.
* @param headerText The header string.
* @param description The description for click action
* @param onShowAllButtonClick Invoked when "Show all" button is clicked.
* @param onShowAllClick Invoked when "Show all" button is clicked.
*/
@Composable
fun HomeSectionHeader(
text: String,
headerText: String,
description: String,
onShowAllClick: () -> Unit = {}
onShowAllClick: () -> Unit
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
SectionHeader(
text = text,
text = headerText,
modifier = Modifier
.weight(1f)
.wrapContentHeight(align = Alignment.Top)
@ -49,9 +49,10 @@ fun HomeSectionHeader(
ClickableText(
text = AnnotatedString(text = stringResource(id = R.string.recent_tabs_show_all)),
modifier = Modifier.semantics {
contentDescription = description
},
modifier = Modifier.padding(start = 16.dp)
.semantics {
contentDescription = description
},
style = TextStyle(
color = FirefoxTheme.colors.textAccent,
fontSize = 14.sp
@ -66,8 +67,9 @@ fun HomeSectionHeader(
private fun HomeSectionsHeaderPreview() {
FirefoxTheme {
HomeSectionHeader(
stringResource(R.string.recent_bookmarks_title),
stringResource(id = R.string.recently_saved_show_all_content_description_2),
headerText = stringResource(R.string.recent_bookmarks_title),
description = stringResource(R.string.recently_saved_show_all_content_description_2),
onShowAllClick = {}
)
}
}
}

@ -12,7 +12,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleOwner
import androidx.navigation.findNavController
@ -20,12 +19,11 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.compose.home.HomeSectionHeader
import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
import org.mozilla.fenix.theme.FirefoxTheme
/**
* View holder for the recent bookmarks header and "Show all" button.
*
* @paramcomposeView [ComposeView] which will be populated with Jetpack Compose UI content.
* @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
* @param interactor [RecentBookmarksInteractor] which will have delegated to all user interactions.
*/
class RecentBookmarksHeaderViewHolder(
@ -53,8 +51,8 @@ class RecentBookmarksHeaderViewHolder(
Spacer(modifier = Modifier.height(40.dp))
HomeSectionHeader(
text = stringResource(R.string.recent_bookmarks_title),
description = stringResource(id = R.string.recently_saved_show_all_content_description_2),
headerText = stringResource(R.string.recent_bookmarks_title),
description = stringResource(R.string.recently_saved_show_all_content_description_2),
onShowAllClick = {
dismissSearchDialogIfDisplayed()
interactor.onShowAllBookmarksClicked()
@ -69,4 +67,3 @@ class RecentBookmarksHeaderViewHolder(
val LAYOUT_ID = View.generateViewId()
}
}

@ -5,11 +5,20 @@
package org.mozilla.fenix.home.recenttabs.view
import android.view.View
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleOwner
import androidx.navigation.findNavController
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.RecentTabsHeaderBinding
import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.compose.home.HomeSectionHeader
import org.mozilla.fenix.home.recenttabs.interactor.RecentTabInteractor
import org.mozilla.fenix.utils.view.ViewHolder
/**
* View holder for the recent tabs header and "Show all" button.
@ -17,16 +26,15 @@ import org.mozilla.fenix.utils.view.ViewHolder
* @param interactor [RecentTabInteractor] which will have delegated to all user interactions.
*/
class RecentTabsHeaderViewHolder(
view: View,
composeView: ComposeView,
viewLifecycleOwner: LifecycleOwner,
private val interactor: RecentTabInteractor
) : ViewHolder(view) {
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
init {
val binding = RecentTabsHeaderBinding.bind(view)
binding.showAllButton.setOnClickListener {
dismissSearchDialogIfDisplayed()
interactor.onRecentTabShowAllClicked()
}
val horizontalPadding =
composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
}
private fun dismissSearchDialogIfDisplayed() {
@ -36,7 +44,25 @@ class RecentTabsHeaderViewHolder(
}
}
@Composable
override fun Content() {
Column {
Spacer(modifier = Modifier.height(40.dp))
HomeSectionHeader(
headerText = stringResource(R.string.recent_tabs_header),
description = stringResource(R.string.recent_tabs_show_all_content_description_2),
onShowAllClick = {
dismissSearchDialogIfDisplayed()
interactor.onRecentTabShowAllClicked()
}
)
Spacer(Modifier.height(16.dp))
}
}
companion object {
const val LAYOUT_ID = R.layout.recent_tabs_header
val LAYOUT_ID = View.generateViewId()
}
}

@ -12,14 +12,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleOwner
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.compose.home.HomeSectionHeader
import org.mozilla.fenix.home.recentvisits.interactor.RecentVisitsInteractor
import org.mozilla.fenix.theme.FirefoxTheme
/**
* View holder for the "Recent visits" section header with the "Show all" button.
@ -45,7 +43,7 @@ class RecentVisitsHeaderViewHolder(
Spacer(modifier = Modifier.height(40.dp))
HomeSectionHeader(
text = stringResource(R.string.history_metadata_header_2),
headerText = stringResource(R.string.history_metadata_header_2),
description = stringResource(R.string.past_explorations_show_all_content_description_2),
onShowAllClick = interactor::onHistoryShowAllClicked,
)

@ -253,13 +253,18 @@ class SessionControlAdapter(
)
RecentVisitsHeaderViewHolder.LAYOUT_ID -> return RecentVisitsHeaderViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner,
interactor
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor
)
RecentBookmarksHeaderViewHolder.LAYOUT_ID -> return RecentBookmarksHeaderViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner,
interactor
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor
)
RecentTabsHeaderViewHolder.LAYOUT_ID -> return RecentTabsHeaderViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor
)
}
@ -300,7 +305,6 @@ class SessionControlAdapter(
view
)
MessageCardViewHolder.LAYOUT_ID -> MessageCardViewHolder(view, interactor)
RecentTabsHeaderViewHolder.LAYOUT_ID -> RecentTabsHeaderViewHolder(view, interactor)
BottomSpacerViewHolder.LAYOUT_ID -> BottomSpacerViewHolder(view)
else -> throw IllegalStateException()
}
@ -314,6 +318,7 @@ class SessionControlAdapter(
is RecentBookmarksViewHolder,
is RecentBookmarksHeaderViewHolder,
is RecentTabViewHolder,
is RecentTabsHeaderViewHolder,
is PocketCategoriesViewHolder,
is PocketRecommendationsHeaderViewHolder,
is PocketStoriesViewHolder -> {

@ -42,7 +42,7 @@ class JumpBackInCFRDialog(val recyclerView: RecyclerView) {
for (index in 0..count) {
val viewHolder = recyclerView.findViewHolderForAdapterPosition(index)
if (viewHolder is RecentTabsHeaderViewHolder) {
return viewHolder.containerView
return viewHolder.composeView
}
}
return null

@ -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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/home_item_horizontal_margin"
android:layout_marginTop="40dp"
android:layout_marginBottom="16dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/header"
style="@style/Header16TextStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="@string/recent_tabs_header"
android:gravity="top"
android:paddingTop="1dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/show_all_button"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/show_all_button"
style="@style/Button14TextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/recent_tabs_show_all_content_description_2"
android:insetTop="0dp"
android:paddingStart="16dp"
android:paddingEnd="0dp"
android:maxLines="1"
android:nestedScrollingEnabled="false"
android:text="@string/recent_tabs_show_all"
android:textColor="@color/fx_mobile_text_color_accent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/header" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -448,7 +448,7 @@
<item name="android:textAllCaps">false</item>
</style>
<style name="Button14TextStyle" parent="TextAppearance.MaterialComponents.Button">
<style name="Button14TextStyle" parent="TextAppearance.MaterialComponents.Button" tools:ignore="UnusedResources">
<item name="android:textSize">14sp</item>
<item name="fontFamily">@font/metropolis</item>
<item name="android:textAllCaps">false</item>

@ -1,40 +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.recenttabs.view
import android.view.LayoutInflater
import androidx.navigation.Navigation
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.RecentTabsHeaderBinding
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
@RunWith(FenixRobolectricTestRunner::class)
class RecentTabsHeaderViewHolderTest {
private lateinit var binding: RecentTabsHeaderBinding
private lateinit var interactor: SessionControlInteractor
@Before
fun setup() {
binding = RecentTabsHeaderBinding.inflate(LayoutInflater.from(testContext))
Navigation.setViewNavController(binding.root, mockk(relaxed = true))
interactor = mockk(relaxed = true)
}
@Test
fun `WHEN show all button is clicked THEN interactor is called`() {
RecentTabsHeaderViewHolder(binding.root, interactor)
binding.showAllButton.performClick()
verify { interactor.onRecentTabShowAllClicked() }
}
}
Loading…
Cancel
Save