For #26421 - Extract synced tabs into it's own viewholder

This commit is contained in:
sarah541 2022-08-10 15:52:10 -04:00 committed by mergify[bot]
parent 979862357d
commit 0b0e31aae8
7 changed files with 96 additions and 27 deletions

View File

@ -183,3 +183,11 @@ fun AppState.shouldShowRecentTabs(settings: Settings): Boolean {
val hasTab = recentTabs.isNotEmpty() || recentSyncedTabState is RecentSyncedTabState.Success
return settings.showRecentTabsFeature && hasTab
}
/**
* Determines whether a recent synced tab section should be shown, based on user preference
* and the availability of Synced tabs.
*/
fun AppState.shouldShowRecentSyncedTabs(settings: Settings): Boolean {
return (settings.enableTaskContinuityEnhancements && recentSyncedTabState is RecentSyncedTabState.Success)
}

View File

@ -0,0 +1,60 @@
/* 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.recentsyncedtabs.view
import android.view.View
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.LifecycleOwner
import mozilla.components.lib.state.ext.observeAsComposableState
import org.mozilla.fenix.R
import org.mozilla.fenix.components.components
import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
import org.mozilla.fenix.home.recentsyncedtabs.interactor.RecentSyncedTabInteractor
/**
* View holder for a recent synced tab item.
*
* @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
* @param recentSyncedTabInteractor [RecentSyncedTabInteractor] which will have delegated to all
* recent synced tab user interactions.
*/
class RecentSyncedTabViewHolder(
composeView: ComposeView,
viewLifecycleOwner: LifecycleOwner,
private val recentSyncedTabInteractor: RecentSyncedTabInteractor,
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
init {
val horizontalPadding =
composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
val verticalPadding =
composeView.resources.getDimensionPixelSize(R.dimen.home_item_vertical_margin)
composeView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, 0)
}
companion object {
val LAYOUT_ID = View.generateViewId()
}
@Composable
override fun Content() {
val recentSyncedTabState =
components.appStore.observeAsComposableState { state -> state.recentSyncedTabState }
recentSyncedTabState.value?.let {
val syncedTab = when (it) {
RecentSyncedTabState.None,
RecentSyncedTabState.Loading -> null
is RecentSyncedTabState.Success -> it.tab
}
RecentSyncedTab(
tab = syncedTab,
onRecentSyncedTabClick = recentSyncedTabInteractor::onRecentSyncedTabClicked,
onSeeAllSyncedTabsButtonClick = recentSyncedTabInteractor::onSyncedTabShowAllClicked,
)
}
}
}

View File

@ -6,22 +6,15 @@ 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 mozilla.components.lib.state.ext.observeAsComposableState
import org.mozilla.fenix.R
import org.mozilla.fenix.components.components
import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
import org.mozilla.fenix.home.recenttabs.interactor.RecentTabInteractor
import org.mozilla.fenix.home.recentsyncedtabs.interactor.RecentSyncedTabInteractor
import org.mozilla.fenix.home.recentsyncedtabs.view.RecentSyncedTab
/**
* View holder for a recent tab item.
@ -36,7 +29,6 @@ class RecentTabViewHolder(
composeView: ComposeView,
viewLifecycleOwner: LifecycleOwner,
private val recentTabInteractor: RecentTabInteractor,
private val recentSyncedTabInteractor: RecentSyncedTabInteractor,
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
init {
@ -52,7 +44,6 @@ class RecentTabViewHolder(
@Composable
override fun Content() {
val recentTabs = components.appStore.observeAsComposableState { state -> state.recentTabs }
val recentSyncedTabState = components.appStore.observeAsComposableState { state -> state.recentSyncedTabState }
Column {
RecentTabs(
@ -65,22 +56,6 @@ class RecentTabViewHolder(
)
)
)
recentSyncedTabState.value?.let {
if (components.settings.enableTaskContinuityEnhancements && it is RecentSyncedTabState.Success) {
Spacer(modifier = Modifier.height(8.dp))
RecentSyncedTab(
tab = it.tab,
onRecentSyncedTabClick = { tab ->
recentSyncedTabInteractor.onRecentSyncedTabClicked(tab)
},
onSeeAllSyncedTabsButtonClick = {
recentSyncedTabInteractor.onSyncedTabShowAllClicked()
},
)
}
}
}
}
}

View File

@ -26,6 +26,7 @@ import org.mozilla.fenix.home.pocket.PocketRecommendationsHeaderViewHolder
import org.mozilla.fenix.home.pocket.PocketStoriesViewHolder
import org.mozilla.fenix.home.recentbookmarks.view.RecentBookmarksHeaderViewHolder
import org.mozilla.fenix.home.recentbookmarks.view.RecentBookmarksViewHolder
import org.mozilla.fenix.home.recentsyncedtabs.view.RecentSyncedTabViewHolder
import org.mozilla.fenix.home.recenttabs.view.RecentTabViewHolder
import org.mozilla.fenix.home.recenttabs.view.RecentTabsHeaderViewHolder
import org.mozilla.fenix.home.recentvisits.view.RecentVisitsHeaderViewHolder
@ -168,6 +169,11 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
object RecentTabsHeader : AdapterItem(RecentTabsHeaderViewHolder.LAYOUT_ID)
object RecentTabItem : AdapterItem(RecentTabViewHolder.LAYOUT_ID)
/**
* Adapter item to hold homescreen synced tabs view.
*/
object RecentSyncedTabItem : AdapterItem(RecentSyncedTabViewHolder.LAYOUT_ID)
object RecentVisitsHeader : AdapterItem(RecentVisitsHeaderViewHolder.LAYOUT_ID)
object RecentVisitsItems : AdapterItem(RecentlyVisitedViewHolder.LAYOUT_ID)
@ -256,6 +262,10 @@ class SessionControlAdapter(
composeView = ComposeView(parent.context),
viewLifecycleOwner = viewLifecycleOwner,
recentTabInteractor = interactor,
)
RecentSyncedTabViewHolder.LAYOUT_ID -> return RecentSyncedTabViewHolder(
composeView = ComposeView(parent.context),
viewLifecycleOwner = viewLifecycleOwner,
recentSyncedTabInteractor = interactor,
)
RecentlyVisitedViewHolder.LAYOUT_ID -> return RecentlyVisitedViewHolder(
@ -338,6 +348,7 @@ class SessionControlAdapter(
is RecentBookmarksViewHolder,
is RecentBookmarksHeaderViewHolder,
is RecentTabViewHolder,
is RecentSyncedTabViewHolder,
is RecentTabsHeaderViewHolder,
is PrivateBrowsingDescriptionViewHolder,
is PocketCategoriesViewHolder,
@ -417,6 +428,7 @@ class SessionControlAdapter(
is RecentlyVisitedViewHolder,
is RecentBookmarksViewHolder,
is RecentTabViewHolder,
is RecentSyncedTabViewHolder,
is PocketStoriesViewHolder -> {
// no-op. This ViewHolder receives the HomeStore as argument and will observe that
// without the need for us to manually update from here the data to be displayed.

View File

@ -15,6 +15,7 @@ import mozilla.components.service.pocket.PocketStory
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.shouldShowRecentSyncedTabs
import org.mozilla.fenix.ext.shouldShowRecentTabs
import org.mozilla.fenix.gleanplumb.Message
import org.mozilla.fenix.home.Mode
@ -37,6 +38,7 @@ internal fun normalModeAdapterItems(
showCollectionsPlaceholder: Boolean,
nimbusMessageCard: Message? = null,
showRecentTab: Boolean,
showRecentSyncedTab: Boolean,
recentVisits: List<RecentlyVisitedItem>,
pocketStories: List<PocketStory>
): List<AdapterItem> {
@ -58,6 +60,9 @@ internal fun normalModeAdapterItems(
shouldShowCustomizeHome = true
items.add(AdapterItem.RecentTabsHeader)
items.add(AdapterItem.RecentTabItem)
if (showRecentSyncedTab) {
items.add(AdapterItem.RecentSyncedTabItem)
}
}
if (settings.showRecentBookmarksFeature && recentBookmarks.isNotEmpty()) {
@ -158,6 +163,7 @@ private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when
showCollectionPlaceholder,
messaging.messageToShow,
shouldShowRecentTabs(settings),
shouldShowRecentSyncedTabs(settings),
recentHistory,
pocketStories
)

View File

@ -77,6 +77,7 @@
<!-- Home Fragment -->
<dimen name="home_fragment_top_toolbar_header_margin">60dp</dimen>
<dimen name="home_item_horizontal_margin">16dp</dimen>
<dimen name="home_item_vertical_margin">8dp</dimen>
<!-- Browser Fragment -->
<!--The size of the gap between the tab preview and content layout.-->

View File

@ -156,8 +156,9 @@ class SessionControlViewTest {
false,
null,
false,
historyMetadata,
pocketStories
showRecentSyncedTab = false,
recentVisits = historyMetadata,
pocketStories = pocketStories
)
assertTrue(results[0] is AdapterItem.TopPlaceholderItem)
@ -192,6 +193,7 @@ class SessionControlViewTest {
false,
nimbusMessageCard,
false,
showRecentSyncedTab = false,
historyMetadata,
pocketStories
)
@ -224,6 +226,7 @@ class SessionControlViewTest {
false,
null,
true,
showRecentSyncedTab = false,
historyMetadata,
pocketStories
)
@ -259,6 +262,7 @@ class SessionControlViewTest {
false,
null,
false,
showRecentSyncedTab = false,
historyMetadata,
pocketStories
)
@ -294,6 +298,7 @@ class SessionControlViewTest {
false,
null,
false,
showRecentSyncedTab = false,
historyMetadata,
pocketStories
)
@ -330,6 +335,7 @@ class SessionControlViewTest {
false,
null,
false,
showRecentSyncedTab = false,
historyMetadata,
pocketStories
)
@ -365,6 +371,7 @@ class SessionControlViewTest {
false,
null,
true,
showRecentSyncedTab = true,
historyMetadata,
pocketStories
)