[fenix] For https://github.com/mozilla-mobile/fenix/issues/23970 - Migrate homescreen recent visits header to compose

pull/600/head
sarah541 3 years ago committed by mergify[bot]
parent 602887e5b6
commit 2040233814

@ -5,8 +5,8 @@
"exposureDescription": "", "exposureDescription": "",
"variables": { "variables": {
"message-location": { "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": "", "exposureDescription": "",
"variables": { "variables": {
"sections-enabled": { "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": "", "exposureDescription": "",
"variables": { "variables": {
"settings-icon": { "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": { "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": { "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": "", "exposureDescription": "",
"variables": { "variables": {
"enabled": { "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 package org.mozilla.fenix.home.recentvisits.view
import android.view.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.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.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. * 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. * interactions.
*/ */
class RecentVisitsHeaderViewHolder( class RecentVisitsHeaderViewHolder(
view: View, composeView: ComposeView,
viewLifecycleOwner: LifecycleOwner,
private val interactor: RecentVisitsInteractor private val interactor: RecentVisitsInteractor
) : ViewHolder(view) { ) : ComposeViewHolder(composeView, viewLifecycleOwner) {
init { init {
val binding = RecentVisitsHeaderBinding.bind(view) val horizontalPadding =
binding.showAllButton.setOnClickListener { composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
interactor.onHistoryShowAllClicked() 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 { companion object {
const val LAYOUT_ID = R.layout.recent_visits_header val LAYOUT_ID = View.generateViewId()
} }
} }

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