For #23970 - Migrate homescreen recent visits header to compose

upstream-sync
sarah541 2 years ago committed by mergify[bot]
parent 1f633edd7d
commit e11c9b2e8f

@ -5,8 +5,8 @@
"exposureDescription": "",
"variables": {
"message-location": {
"type": "string",
"description": "Where is the message to be put."
"description": "Where is the message to be put.",
"type": "string"
}
}
},
@ -16,8 +16,8 @@
"exposureDescription": "",
"variables": {
"sections-enabled": {
"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."
"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"
}
}
},
@ -54,16 +54,16 @@
"exposureDescription": "",
"variables": {
"settings-icon": {
"type": "string",
"description": "The drawable displayed in the app menu for Settings"
"description": "The drawable displayed in the app menu for Settings",
"type": "string"
},
"settings-punctuation": {
"type": "string",
"description": "The emoji displayed in the Settings screen title."
"description": "The emoji displayed in the Settings screen title.",
"type": "string"
},
"settings-title": {
"type": "string",
"description": "The title of displayed in the Settings screen and app menu."
"description": "The title of displayed in the Settings screen and app menu.",
"type": "string"
}
}
},
@ -73,8 +73,8 @@
"exposureDescription": "",
"variables": {
"enabled": {
"type": "boolean",
"description": "If true, the feature shows up on the homescreen and on the new tab screen."
"description": "If true, the feature shows up on the homescreen and on the new tab screen.",
"type": "boolean"
}
}
}

@ -0,0 +1,73 @@
/* 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.compose.home
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.text.ClickableText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
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.sp
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.SectionHeader
import org.mozilla.fenix.theme.FirefoxTheme
/**
* Homepage header.
*
* @param text The header string.
* @param description The description for click action
* @param onShowAllButtonClick Invoked when "Show all" button is clicked.
*/
@Composable
fun HomeSectionHeader(
text: String,
description: String,
onShowAllClick: () -> Unit = {}
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
SectionHeader(
text = text,
modifier = Modifier
.weight(1f)
.wrapContentHeight(align = Alignment.Top)
)
ClickableText(
text = AnnotatedString(text = stringResource(id = R.string.recent_tabs_show_all)),
modifier = Modifier.semantics {
contentDescription = description
},
style = TextStyle(
color = FirefoxTheme.colors.textAccent,
fontSize = 14.sp
),
onClick = { onShowAllClick() }
)
}
}
@Composable
@Preview
private fun HomeSectionsHeaderPreview() {
FirefoxTheme {
HomeSectionHeader(
stringResource(R.string.recent_bookmarks_title),
stringResource(id = R.string.recently_saved_show_all_content_description_2),
)
}
}

@ -5,10 +5,21 @@
package org.mozilla.fenix.home.recentvisits.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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleOwner
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.RecentVisitsHeaderBinding
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.utils.view.ViewHolder
import org.mozilla.fenix.theme.FirefoxTheme
/**
* View holder for the "Recent visits" section header with the "Show all" button.
@ -17,18 +28,33 @@ import org.mozilla.fenix.utils.view.ViewHolder
* interactions.
*/
class RecentVisitsHeaderViewHolder(
view: View,
composeView: ComposeView,
viewLifecycleOwner: LifecycleOwner,
private val interactor: RecentVisitsInteractor
) : ViewHolder(view) {
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
init {
val binding = RecentVisitsHeaderBinding.bind(view)
binding.showAllButton.setOnClickListener {
interactor.onHistoryShowAllClicked()
val horizontalPadding =
composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
}
@Composable
override fun Content() {
Column {
Spacer(modifier = Modifier.height(40.dp))
HomeSectionHeader(
text = stringResource(R.string.history_metadata_header_2),
description = stringResource(R.string.past_explorations_show_all_content_description_2),
onShowAllClick = interactor::onHistoryShowAllClicked,
)
Spacer(Modifier.height(16.dp))
}
}
companion object {
const val LAYOUT_ID = R.layout.recent_visits_header
val LAYOUT_ID = View.generateViewId()
}
}

@ -251,6 +251,11 @@ class SessionControlAdapter(
interactor = interactor,
metrics = components.analytics.metrics
)
RecentVisitsHeaderViewHolder.LAYOUT_ID -> return RecentVisitsHeaderViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner,
interactor
)
}
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
@ -292,10 +297,6 @@ class SessionControlAdapter(
MessageCardViewHolder.LAYOUT_ID -> MessageCardViewHolder(view, interactor)
RecentTabsHeaderViewHolder.LAYOUT_ID -> RecentTabsHeaderViewHolder(view, interactor)
RecentBookmarksHeaderViewHolder.LAYOUT_ID -> RecentBookmarksHeaderViewHolder(view, interactor)
RecentVisitsHeaderViewHolder.LAYOUT_ID -> RecentVisitsHeaderViewHolder(
view,
interactor
)
BottomSpacerViewHolder.LAYOUT_ID -> BottomSpacerViewHolder(view)
else -> throw IllegalStateException()
}
@ -305,6 +306,7 @@ class SessionControlAdapter(
when (holder) {
is CustomizeHomeButtonViewHolder,
is RecentlyVisitedViewHolder,
is RecentVisitsHeaderViewHolder,
is RecentBookmarksViewHolder,
is RecentTabViewHolder,
is PocketCategoriesViewHolder,

@ -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/history_metadata_header_2"
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/past_explorations_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>

@ -1,38 +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.recentvisits.view
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.RecentVisitsHeaderBinding
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
@RunWith(FenixRobolectricTestRunner::class)
class RecentVisitsHeaderViewHolderTest {
private lateinit var binding: RecentVisitsHeaderBinding
private lateinit var interactor: SessionControlInteractor
@Before
fun setup() {
binding = RecentVisitsHeaderBinding.inflate(LayoutInflater.from(testContext))
interactor = mockk(relaxed = true)
}
@Test
fun `WHEN show all button is clicked THEN interactor is called`() {
RecentVisitsHeaderViewHolder(binding.root, interactor)
binding.showAllButton.performClick()
verify { interactor.onHistoryShowAllClicked() }
}
}
Loading…
Cancel
Save