mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-17 15:26:23 +00:00
[fenix] For https://github.com/mozilla-mobile/fenix/issues/22383: Propagate ViewTreeLifecycleOwner to composable view holders.
This commit is contained in:
parent
5cc5b50595
commit
e297e494c2
@ -0,0 +1,50 @@
|
||||
/* 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
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ViewTreeLifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.savedstate.SavedStateRegistryOwner
|
||||
import androidx.savedstate.ViewTreeSavedStateRegistryOwner
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
/**
|
||||
* [RecyclerView.ViewHolder] used for Jetpack Compose UI content .
|
||||
*
|
||||
* @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
|
||||
* @param viewLifecycleOwner [LifecycleOwner] life cycle owner for the view.
|
||||
*/
|
||||
abstract class ComposeViewHolder(
|
||||
val composeView: ComposeView,
|
||||
viewLifecycleOwner: LifecycleOwner
|
||||
) : RecyclerView.ViewHolder(composeView) {
|
||||
|
||||
/**
|
||||
* Composable that contains the content for a specific [ComposeViewHolder] implementation.
|
||||
*/
|
||||
@Composable
|
||||
abstract fun Content()
|
||||
|
||||
init {
|
||||
composeView.setViewCompositionStrategy(
|
||||
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
|
||||
)
|
||||
composeView.setContent {
|
||||
FirefoxTheme {
|
||||
Content()
|
||||
}
|
||||
}
|
||||
|
||||
ViewTreeLifecycleOwner.set(composeView, viewLifecycleOwner)
|
||||
ViewTreeSavedStateRegistryOwner.set(
|
||||
composeView,
|
||||
viewLifecycleOwner as SavedStateRegistryOwner
|
||||
)
|
||||
}
|
||||
}
|
@ -17,16 +17,16 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import mozilla.components.lib.state.ext.observeAsComposableState
|
||||
import mozilla.components.service.pocket.PocketRecommendedStory
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.compose.SectionHeader
|
||||
import org.mozilla.fenix.home.HomeFragmentStore
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
internal const val POCKET_STORIES_TO_SHOW_COUNT = 8
|
||||
internal const val POCKET_CATEGORIES_SELECTED_AT_A_TIME_COUNT = 8
|
||||
@ -40,35 +40,30 @@ internal const val POCKET_CATEGORIES_SELECTED_AT_A_TIME_COUNT = 8
|
||||
* @param interactor [PocketStoriesInteractor] callback for user interaction.
|
||||
*/
|
||||
class PocketStoriesViewHolder(
|
||||
val composeView: ComposeView,
|
||||
composeView: ComposeView,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
val store: HomeFragmentStore,
|
||||
val interactor: PocketStoriesInteractor
|
||||
) : RecyclerView.ViewHolder(composeView) {
|
||||
|
||||
init {
|
||||
composeView.setViewCompositionStrategy(
|
||||
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
|
||||
)
|
||||
composeView.setContent {
|
||||
FirefoxTheme {
|
||||
PocketStories(
|
||||
store,
|
||||
interactor::onStoriesShown,
|
||||
interactor::onStoryClicked,
|
||||
interactor::onCategoryClicked,
|
||||
interactor::onDiscoverMoreClicked,
|
||||
interactor::onLearnMoreClicked,
|
||||
with(composeView.resources) {
|
||||
getDimensionPixelSize(R.dimen.home_item_horizontal_margin) / displayMetrics.density
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
|
||||
|
||||
companion object {
|
||||
val LAYOUT_ID = View.generateViewId()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
PocketStories(
|
||||
store,
|
||||
interactor::onStoriesShown,
|
||||
interactor::onStoryClicked,
|
||||
interactor::onCategoryClicked,
|
||||
interactor::onDiscoverMoreClicked,
|
||||
interactor::onLearnMoreClicked,
|
||||
with(composeView.resources) {
|
||||
getDimensionPixelSize(R.dimen.home_item_horizontal_margin) / displayMetrics.density
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -110,7 +105,12 @@ fun PocketStories(
|
||||
|
||||
Spacer(Modifier.height(17.dp))
|
||||
|
||||
PocketStories(stories ?: emptyList(), horizontalPadding.dp, onStoryClicked, onDiscoverMoreClicked)
|
||||
PocketStories(
|
||||
stories ?: emptyList(),
|
||||
horizontalPadding.dp,
|
||||
onStoryClicked,
|
||||
onDiscoverMoreClicked
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(24.dp))
|
||||
|
||||
|
@ -5,42 +5,39 @@
|
||||
package org.mozilla.fenix.home.recentbookmarks.view
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import mozilla.components.lib.state.ext.observeAsComposableState
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.home.HomeFragmentStore
|
||||
import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.utils.view.ViewHolder
|
||||
|
||||
class RecentBookmarksViewHolder(
|
||||
val composeView: ComposeView,
|
||||
composeView: ComposeView,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
private val store: HomeFragmentStore,
|
||||
val interactor: RecentBookmarksInteractor,
|
||||
val metrics: MetricController
|
||||
) : ViewHolder(composeView) {
|
||||
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
|
||||
|
||||
init {
|
||||
metrics.track(Event.RecentBookmarksShown)
|
||||
|
||||
composeView.setViewCompositionStrategy(
|
||||
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
|
||||
)
|
||||
composeView.setContent {
|
||||
val recentBookmarks = store.observeAsComposableState { state -> state.recentBookmarks }
|
||||
|
||||
FirefoxTheme {
|
||||
RecentBookmarks(
|
||||
bookmarks = recentBookmarks.value ?: emptyList(),
|
||||
onRecentBookmarkClick = interactor::onRecentBookmarkClicked
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val LAYOUT_ID = View.generateViewId()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val recentBookmarks = store.observeAsComposableState { state -> state.recentBookmarks }
|
||||
|
||||
RecentBookmarks(
|
||||
bookmarks = recentBookmarks.value ?: emptyList(),
|
||||
onRecentBookmarkClick = interactor::onRecentBookmarkClicked
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -5,14 +5,14 @@
|
||||
package org.mozilla.fenix.home.recenttabs.view
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import mozilla.components.lib.state.ext.observeAsComposableState
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.home.HomeFragmentStore
|
||||
import org.mozilla.fenix.home.recenttabs.interactor.RecentTabInteractor
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.utils.view.ViewHolder
|
||||
|
||||
/**
|
||||
* View holder for a recent tab item.
|
||||
@ -22,32 +22,30 @@ import org.mozilla.fenix.utils.view.ViewHolder
|
||||
* @param interactor [RecentTabInteractor] which will have delegated to all user interactions.
|
||||
*/
|
||||
class RecentTabViewHolder(
|
||||
val composeView: ComposeView,
|
||||
composeView: ComposeView,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
private val store: HomeFragmentStore,
|
||||
private val interactor: RecentTabInteractor
|
||||
) : ViewHolder(composeView) {
|
||||
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
|
||||
|
||||
init {
|
||||
val horizontalPadding = composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
|
||||
val horizontalPadding =
|
||||
composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
|
||||
composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
|
||||
|
||||
composeView.setViewCompositionStrategy(
|
||||
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
|
||||
)
|
||||
composeView.setContent {
|
||||
val recentTabs = store.observeAsComposableState { state -> state.recentTabs }
|
||||
|
||||
FirefoxTheme {
|
||||
RecentTabs(
|
||||
recentTabs = recentTabs.value ?: emptyList(),
|
||||
onRecentTabClick = { interactor.onRecentTabClicked(it) },
|
||||
onRecentSearchGroupClicked = { interactor.onRecentSearchGroupClicked(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val LAYOUT_ID = View.generateViewId()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val recentTabs = store.observeAsComposableState { state -> state.recentTabs }
|
||||
|
||||
RecentTabs(
|
||||
recentTabs = recentTabs.value ?: emptyList(),
|
||||
onRecentTabClick = { interactor.onRecentTabClicked(it) },
|
||||
onRecentSearchGroupClicked = { interactor.onRecentSearchGroupClicked(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -5,20 +5,20 @@
|
||||
package org.mozilla.fenix.home.recentvisits.view
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import mozilla.components.lib.state.ext.observeAsComposableState
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.home.HomeFragmentStore
|
||||
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
|
||||
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryGroup
|
||||
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryHighlight
|
||||
import org.mozilla.fenix.home.recentvisits.interactor.RecentVisitsInteractor
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.utils.view.ViewHolder
|
||||
|
||||
/**
|
||||
* View holder for [RecentlyVisitedItem]s.
|
||||
@ -29,50 +29,50 @@ import org.mozilla.fenix.utils.view.ViewHolder
|
||||
* @property metrics [MetricController] that handles telemetry events.
|
||||
*/
|
||||
class RecentlyVisitedViewHolder(
|
||||
val composeView: ComposeView,
|
||||
composeView: ComposeView,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
private val store: HomeFragmentStore,
|
||||
private val interactor: RecentVisitsInteractor,
|
||||
private val metrics: MetricController
|
||||
) : ViewHolder(composeView) {
|
||||
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
|
||||
|
||||
init {
|
||||
val horizontalPadding = composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
|
||||
val horizontalPadding =
|
||||
composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
|
||||
composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
|
||||
}
|
||||
|
||||
composeView.setViewCompositionStrategy(
|
||||
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
|
||||
)
|
||||
composeView.setContent {
|
||||
val recentVisits = store.observeAsComposableState { state -> state.recentHistory }
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val recentVisits = store.observeAsComposableState { state -> state.recentHistory }
|
||||
|
||||
FirefoxTheme {
|
||||
RecentlyVisited(
|
||||
recentVisits = recentVisits.value ?: emptyList(),
|
||||
menuItems = listOfNotNull(
|
||||
RecentVisitMenuItem(
|
||||
title = stringResource(R.string.recently_visited_menu_item_remove),
|
||||
onClick = { visit ->
|
||||
when (visit) {
|
||||
is RecentHistoryGroup -> interactor.onRemoveRecentHistoryGroup(visit.title)
|
||||
is RecentHistoryHighlight -> interactor.onRemoveRecentHistoryHighlight(visit.url)
|
||||
}
|
||||
}
|
||||
)
|
||||
),
|
||||
onRecentVisitClick = { recentlyVisitedItem, pageNumber ->
|
||||
when (recentlyVisitedItem) {
|
||||
is RecentHistoryHighlight -> {
|
||||
interactor.onRecentHistoryHighlightClicked(recentlyVisitedItem)
|
||||
}
|
||||
is RecentHistoryGroup -> {
|
||||
metrics.track(Event.HistoryRecentSearchesTapped(pageNumber.toString()))
|
||||
interactor.onRecentHistoryGroupClicked(recentlyVisitedItem)
|
||||
}
|
||||
RecentlyVisited(
|
||||
recentVisits = recentVisits.value ?: emptyList(),
|
||||
menuItems = listOfNotNull(
|
||||
RecentVisitMenuItem(
|
||||
title = stringResource(R.string.recently_visited_menu_item_remove),
|
||||
onClick = { visit ->
|
||||
when (visit) {
|
||||
is RecentHistoryGroup -> interactor.onRemoveRecentHistoryGroup(visit.title)
|
||||
is RecentHistoryHighlight -> interactor.onRemoveRecentHistoryHighlight(
|
||||
visit.url
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
),
|
||||
onRecentVisitClick = { recentlyVisitedItem, pageNumber ->
|
||||
when (recentlyVisitedItem) {
|
||||
is RecentHistoryHighlight -> {
|
||||
interactor.onRecentHistoryHighlightClicked(recentlyVisitedItem)
|
||||
}
|
||||
is RecentHistoryGroup -> {
|
||||
metrics.track(Event.HistoryRecentSearchesTapped(pageNumber.toString()))
|
||||
interactor.onRecentHistoryGroupClicked(recentlyVisitedItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -19,6 +19,7 @@ import mozilla.components.feature.top.sites.TopSite.Type.FRECENT
|
||||
import mozilla.components.ui.widgets.WidgetSiteItemView
|
||||
import org.mozilla.fenix.components.Components
|
||||
import org.mozilla.fenix.components.tips.Tip
|
||||
import org.mozilla.fenix.home.BottomSpacerViewHolder
|
||||
import org.mozilla.fenix.home.HomeFragmentStore
|
||||
import org.mozilla.fenix.home.TopPlaceholderViewHolder
|
||||
import org.mozilla.fenix.home.pocket.PocketStoriesViewHolder
|
||||
@ -44,7 +45,6 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTh
|
||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingToolbarPositionPickerViewHolder
|
||||
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder
|
||||
import org.mozilla.fenix.home.tips.ButtonTipViewHolder
|
||||
import org.mozilla.fenix.home.BottomSpacerViewHolder
|
||||
import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
|
||||
import mozilla.components.feature.tab.collections.Tab as ComponentTab
|
||||
|
||||
@ -211,26 +211,31 @@ class SessionControlAdapter(
|
||||
when (viewType) {
|
||||
CustomizeHomeButtonViewHolder.LAYOUT_ID -> return CustomizeHomeButtonViewHolder(
|
||||
composeView = ComposeView(parent.context),
|
||||
viewLifecycleOwner,
|
||||
interactor = interactor
|
||||
)
|
||||
PocketStoriesViewHolder.LAYOUT_ID -> return PocketStoriesViewHolder(
|
||||
composeView = ComposeView(parent.context),
|
||||
viewLifecycleOwner,
|
||||
store = store,
|
||||
interactor = interactor
|
||||
)
|
||||
RecentBookmarksViewHolder.LAYOUT_ID -> return RecentBookmarksViewHolder(
|
||||
composeView = ComposeView(parent.context),
|
||||
viewLifecycleOwner,
|
||||
store = store,
|
||||
interactor = interactor,
|
||||
metrics = components.analytics.metrics
|
||||
)
|
||||
RecentTabViewHolder.LAYOUT_ID -> return RecentTabViewHolder(
|
||||
composeView = ComposeView(parent.context),
|
||||
viewLifecycleOwner,
|
||||
store = store,
|
||||
interactor = interactor
|
||||
)
|
||||
RecentlyVisitedViewHolder.LAYOUT_ID -> return RecentlyVisitedViewHolder(
|
||||
composeView = ComposeView(parent.context),
|
||||
viewLifecycleOwner,
|
||||
store = store,
|
||||
interactor = interactor,
|
||||
metrics = components.analytics.metrics
|
||||
|
@ -18,44 +18,39 @@ import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.Font
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import mozilla.components.ui.colors.PhotonColors
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.home.sessioncontrol.CustomizeHomeIteractor
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
class CustomizeHomeButtonViewHolder(
|
||||
val composeView: ComposeView,
|
||||
composeView: ComposeView,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
private val interactor: CustomizeHomeIteractor
|
||||
) : RecyclerView.ViewHolder(composeView) {
|
||||
|
||||
init {
|
||||
composeView.setViewCompositionStrategy(
|
||||
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
|
||||
)
|
||||
composeView.setContent {
|
||||
FirefoxTheme {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(68.dp))
|
||||
|
||||
CustomizeHomeButton(
|
||||
onButtonClick = { interactor.openCustomizeHomePage() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) : ComposeViewHolder(composeView, viewLifecycleOwner) {
|
||||
|
||||
companion object {
|
||||
val LAYOUT_ID = View.generateViewId()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(68.dp))
|
||||
|
||||
CustomizeHomeButton(
|
||||
onButtonClick = { interactor.openCustomizeHomePage() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user