For #26520 - Color homepage cards via wallpaper card colors
This commit is contained in:
parent
374bff84c4
commit
f4e7471aea
|
@ -5,12 +5,14 @@
|
|||
package org.mozilla.fenix.home.pocket
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
@ -24,6 +26,7 @@ import org.mozilla.fenix.compose.ComposeViewHolder
|
|||
import org.mozilla.fenix.compose.home.HomeSectionHeader
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.theme.Theme
|
||||
import org.mozilla.fenix.wallpapers.WallpaperState
|
||||
|
||||
internal const val POCKET_CATEGORIES_SELECTED_AT_A_TIME_COUNT = 8
|
||||
|
||||
|
@ -55,12 +58,37 @@ class PocketCategoriesViewHolder(
|
|||
val categoriesSelections = components.appStore
|
||||
.observeAsComposableState { state -> state.pocketStoriesCategoriesSelections }.value
|
||||
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
|
||||
var selectedBackgroundColor: Color? = null
|
||||
var unselectedBackgroundColor: Color? = null
|
||||
var selectedTextColor: Color? = null
|
||||
var unselectedTextColor: Color? = null
|
||||
wallpaperState.composeRunIfWallpaperCardColorsAreAvailable { cardColorLight, cardColorDark ->
|
||||
if (isSystemInDarkTheme()) {
|
||||
selectedBackgroundColor = cardColorDark
|
||||
unselectedBackgroundColor = cardColorLight
|
||||
selectedTextColor = FirefoxTheme.colors.textActionPrimary
|
||||
unselectedTextColor = FirefoxTheme.colors.textActionSecondary
|
||||
} else {
|
||||
selectedBackgroundColor = cardColorLight
|
||||
unselectedBackgroundColor = cardColorDark
|
||||
selectedTextColor = FirefoxTheme.colors.textActionSecondary
|
||||
unselectedTextColor = FirefoxTheme.colors.textActionPrimary
|
||||
}
|
||||
}
|
||||
|
||||
// See the detailed comment in PocketStoriesViewHolder for reasoning behind this change.
|
||||
if (!homeScreenReady) return
|
||||
Column {
|
||||
Spacer(Modifier.height(24.dp))
|
||||
|
||||
PocketTopics(
|
||||
selectedBackgroundColor = selectedBackgroundColor,
|
||||
unselectedBackgroundColor = unselectedBackgroundColor,
|
||||
selectedTextColor = selectedTextColor,
|
||||
unselectedTextColor = unselectedTextColor,
|
||||
categories = categories ?: emptyList(),
|
||||
categoriesSelections = categoriesSelections ?: emptyList(),
|
||||
onCategoryClick = interactor::onCategoryClicked,
|
||||
|
@ -75,6 +103,10 @@ class PocketCategoriesViewHolder(
|
|||
|
||||
@Composable
|
||||
private fun PocketTopics(
|
||||
selectedTextColor: Color? = null,
|
||||
unselectedTextColor: Color? = null,
|
||||
selectedBackgroundColor: Color? = null,
|
||||
unselectedBackgroundColor: Color? = null,
|
||||
categories: List<PocketRecommendedStoriesCategory> = emptyList(),
|
||||
categoriesSelections: List<PocketRecommendedStoriesSelectedCategory> = emptyList(),
|
||||
onCategoryClick: (PocketRecommendedStoriesCategory) -> Unit,
|
||||
|
@ -89,6 +121,10 @@ private fun PocketTopics(
|
|||
PocketStoriesCategories(
|
||||
categories = categories,
|
||||
selections = categoriesSelections,
|
||||
selectedTextColor = selectedTextColor,
|
||||
unselectedTextColor = unselectedTextColor,
|
||||
selectedBackgroundColor = selectedBackgroundColor,
|
||||
unselectedBackgroundColor = unselectedBackgroundColor,
|
||||
onCategoryClick = onCategoryClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
|
|
|
@ -98,11 +98,13 @@ private val placeholderStory = PocketRecommendedStory("", "", "", "", "", 0, 0)
|
|||
* Displays a single [PocketRecommendedStory].
|
||||
*
|
||||
* @param story The [PocketRecommendedStory] to be displayed.
|
||||
* @param backgroundColor The background [Color] of the story.
|
||||
* @param onStoryClick Callback for when the user taps on this story.
|
||||
*/
|
||||
@Composable
|
||||
fun PocketStory(
|
||||
@PreviewParameter(PocketStoryProvider::class) story: PocketRecommendedStory,
|
||||
backgroundColor: Color,
|
||||
onStoryClick: (PocketRecommendedStory) -> Unit,
|
||||
) {
|
||||
val imageUrl = story.imageUrl.replace(
|
||||
|
@ -113,6 +115,7 @@ fun PocketStory(
|
|||
val isValidTimeToRead = story.timeToRead >= 0
|
||||
ListItemTabLarge(
|
||||
imageUrl = imageUrl,
|
||||
backgroundColor = backgroundColor,
|
||||
onClick = { onStoryClick(story) },
|
||||
title = {
|
||||
Text(
|
||||
|
@ -151,11 +154,13 @@ fun PocketStory(
|
|||
* Displays a single [PocketSponsoredStory].
|
||||
*
|
||||
* @param story The [PocketSponsoredStory] to be displayed.
|
||||
* @param backgroundColor The background [Color] of the story.
|
||||
* @param onStoryClick Callback for when the user taps on this story.
|
||||
*/
|
||||
@Composable
|
||||
fun PocketSponsoredStory(
|
||||
story: PocketSponsoredStory,
|
||||
backgroundColor: Color,
|
||||
onStoryClick: (PocketSponsoredStory) -> Unit,
|
||||
) {
|
||||
val (imageWidth, imageHeight) = with(LocalDensity.current) {
|
||||
|
@ -168,6 +173,7 @@ fun PocketSponsoredStory(
|
|||
|
||||
ListItemTabSurface(
|
||||
imageUrl = imageUrl,
|
||||
backgroundColor = backgroundColor,
|
||||
onClick = { onStoryClick(story) },
|
||||
) {
|
||||
Text(
|
||||
|
@ -208,14 +214,17 @@ fun PocketSponsoredStory(
|
|||
* @param stories The list of [PocketStory]ies to be displayed. Expect a list with 8 items.
|
||||
* @param contentPadding Dimension for padding the content after it has been clipped.
|
||||
* This space will be used for shadows and also content rendering when the list is scrolled.
|
||||
* @param backgroundColor The background [Color] of each story.
|
||||
* @param onStoryShown Callback for when a certain story is visible to the user.
|
||||
* @param onStoryClicked Callback for when the user taps on a recommended story.
|
||||
* @param onDiscoverMoreClicked Callback for when the user taps an element which contains an
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
fun PocketStories(
|
||||
@PreviewParameter(PocketStoryProvider::class) stories: List<PocketStory>,
|
||||
contentPadding: Dp,
|
||||
backgroundColor: Color = FirefoxTheme.colors.layer2,
|
||||
onStoryShown: (PocketStory, Pair<Int, Int>) -> Unit,
|
||||
onStoryClicked: (PocketStory, Pair<Int, Int>) -> Unit,
|
||||
onDiscoverMoreClicked: (String) -> Unit,
|
||||
|
@ -241,7 +250,10 @@ fun PocketStories(
|
|||
onDiscoverMoreClicked("https://getpocket.com/explore?$POCKET_FEATURE_UTM_KEY_VALUE")
|
||||
}
|
||||
} else if (story is PocketRecommendedStory) {
|
||||
PocketStory(story) {
|
||||
PocketStory(
|
||||
story = story,
|
||||
backgroundColor = backgroundColor,
|
||||
) {
|
||||
val uri = Uri.parse(story.url)
|
||||
.buildUpon()
|
||||
.appendQueryParameter(URI_PARAM_UTM_KEY, POCKET_STORIES_UTM_VALUE)
|
||||
|
@ -254,7 +266,10 @@ fun PocketStories(
|
|||
onStoryShown(story, rowIndex to columnIndex)
|
||||
},
|
||||
) {
|
||||
PocketSponsoredStory(story) {
|
||||
PocketSponsoredStory(
|
||||
story = story,
|
||||
backgroundColor = backgroundColor,
|
||||
) {
|
||||
onStoryClicked(story, rowIndex to columnIndex)
|
||||
}
|
||||
}
|
||||
|
@ -359,13 +374,22 @@ private fun Rect.getIntersectPercentage(realSize: IntSize, other: Rect): Float {
|
|||
*
|
||||
* @param categories The categories needed to be displayed.
|
||||
* @param selections List of categories currently selected.
|
||||
* @param selectedTextColor Text [Color] when the category is selected.
|
||||
* @param unselectedTextColor Text [Color] when the category is not selected.
|
||||
* @param selectedBackgroundColor Background [Color] when the category is selected.
|
||||
* @param unselectedBackgroundColor Background [Color] when the category is not selected.
|
||||
* @param onCategoryClick Callback for when the user taps a category.
|
||||
* @param modifier [Modifier] to be applied to the layout.
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
fun PocketStoriesCategories(
|
||||
categories: List<PocketRecommendedStoriesCategory>,
|
||||
selections: List<PocketRecommendedStoriesSelectedCategory>,
|
||||
selectedTextColor: Color? = null,
|
||||
unselectedTextColor: Color? = null,
|
||||
selectedBackgroundColor: Color? = null,
|
||||
unselectedBackgroundColor: Color? = null,
|
||||
onCategoryClick: (PocketRecommendedStoriesCategory) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
@ -375,7 +399,14 @@ fun PocketStoriesCategories(
|
|||
verticalItemsSpacing = 16.dp,
|
||||
) {
|
||||
categories.filter { it.name != POCKET_STORIES_DEFAULT_CATEGORY_NAME }.forEach { category ->
|
||||
SelectableChip(category.name, selections.map { it.name }.contains(category.name)) {
|
||||
SelectableChip(
|
||||
text = category.name,
|
||||
isSelected = selections.map { it.name }.contains(category.name),
|
||||
selectedTextColor = selectedTextColor,
|
||||
unselectedTextColor = unselectedTextColor,
|
||||
selectedBackgroundColor = selectedBackgroundColor,
|
||||
unselectedBackgroundColor = unselectedBackgroundColor,
|
||||
) {
|
||||
onCategoryClick(category)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import mozilla.components.lib.state.ext.observeAsComposableState
|
||||
import mozilla.components.service.pocket.PocketStory.PocketRecommendedStory
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.R.dimen
|
||||
import org.mozilla.fenix.components.components
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.compose.home.HomeSectionHeader
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.theme.Theme
|
||||
import org.mozilla.fenix.wallpapers.WallpaperState
|
||||
|
||||
/**
|
||||
* [RecyclerView.ViewHolder] for displaying the list of [PocketRecommendedStory]s from [AppStore].
|
||||
|
@ -49,7 +49,7 @@ class PocketStoriesViewHolder(
|
|||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val horizontalPadding = dimensionResource(dimen.home_item_horizontal_margin)
|
||||
val horizontalPadding = dimensionResource(R.dimen.home_item_horizontal_margin)
|
||||
|
||||
val homeScreenReady = components.appStore
|
||||
.observeAsComposableState { state -> state.firstFrameDrawn }.value ?: false
|
||||
|
@ -57,6 +57,9 @@ class PocketStoriesViewHolder(
|
|||
val stories = components.appStore
|
||||
.observeAsComposableState { state -> state.pocketStories }.value
|
||||
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
|
||||
/* This was originally done to address this perf issue:
|
||||
* https://github.com/mozilla-mobile/fenix/issues/25545 for details.
|
||||
* It was determined that Pocket content was becoming available before the first frame was
|
||||
|
@ -88,11 +91,12 @@ class PocketStoriesViewHolder(
|
|||
Spacer(Modifier.height(16.dp))
|
||||
|
||||
PocketStories(
|
||||
stories ?: emptyList(),
|
||||
horizontalPadding,
|
||||
interactor::onStoryShown,
|
||||
interactor::onStoryClicked,
|
||||
interactor::onDiscoverMoreClicked,
|
||||
stories = stories ?: emptyList(),
|
||||
contentPadding = horizontalPadding,
|
||||
backgroundColor = wallpaperState.wallpaperCardColor,
|
||||
onStoryShown = interactor::onStoryShown,
|
||||
onStoryClicked = interactor::onStoryClicked,
|
||||
onDiscoverMoreClicked = interactor::onDiscoverMoreClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +117,7 @@ fun PocketStoriesViewHolderPreview() {
|
|||
PocketStories(
|
||||
stories = getFakePocketStories(8),
|
||||
contentPadding = 0.dp,
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
onStoryShown = { _, _ -> },
|
||||
onStoryClicked = { _, _ -> },
|
||||
onDiscoverMoreClicked = {},
|
||||
|
|
|
@ -36,6 +36,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
@ -64,6 +65,7 @@ private val imageModifier = Modifier
|
|||
*
|
||||
* @param bookmarks List of [RecentBookmark]s to display.
|
||||
* @param menuItems List of [RecentBookmarksMenuItem] shown when long clicking a [RecentBookmarkItem]
|
||||
* @param backgroundColor The background [Color] of each bookmark.
|
||||
* @param onRecentBookmarkClick Invoked when the user clicks on a recent bookmark.
|
||||
* @param onRecentBookmarkLongClick Invoked when the user long clicks on a recent bookmark.
|
||||
*/
|
||||
|
@ -71,6 +73,7 @@ private val imageModifier = Modifier
|
|||
fun RecentBookmarks(
|
||||
bookmarks: List<RecentBookmark>,
|
||||
menuItems: List<RecentBookmarksMenuItem>,
|
||||
backgroundColor: Color,
|
||||
onRecentBookmarkClick: (RecentBookmark) -> Unit = {},
|
||||
onRecentBookmarkLongClick: () -> Unit = {},
|
||||
) {
|
||||
|
@ -82,6 +85,7 @@ fun RecentBookmarks(
|
|||
RecentBookmarkItem(
|
||||
bookmark = bookmark,
|
||||
menuItems = menuItems,
|
||||
backgroundColor = backgroundColor,
|
||||
onRecentBookmarkClick = onRecentBookmarkClick,
|
||||
onRecentBookmarkLongClick = onRecentBookmarkLongClick,
|
||||
)
|
||||
|
@ -93,6 +97,8 @@ fun RecentBookmarks(
|
|||
* A recent bookmark item.
|
||||
*
|
||||
* @param bookmark The [RecentBookmark] to display.
|
||||
* @param menuItems The list of [RecentBookmarksMenuItem] shown when long clicking on the recent bookmark item.
|
||||
* @param backgroundColor The background [Color] of the recent bookmark item.
|
||||
* @param onRecentBookmarkClick Invoked when the user clicks on the recent bookmark item.
|
||||
* @param onRecentBookmarkLongClick Invoked when the user long clicks on the recent bookmark item.
|
||||
*/
|
||||
|
@ -101,6 +107,7 @@ fun RecentBookmarks(
|
|||
private fun RecentBookmarkItem(
|
||||
bookmark: RecentBookmark,
|
||||
menuItems: List<RecentBookmarksMenuItem>,
|
||||
backgroundColor: Color,
|
||||
onRecentBookmarkClick: (RecentBookmark) -> Unit = {},
|
||||
onRecentBookmarkLongClick: () -> Unit = {},
|
||||
) {
|
||||
|
@ -118,7 +125,7 @@ private fun RecentBookmarkItem(
|
|||
},
|
||||
),
|
||||
shape = cardShape,
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
backgroundColor = backgroundColor,
|
||||
elevation = 6.dp,
|
||||
) {
|
||||
Column(
|
||||
|
@ -277,6 +284,7 @@ private fun RecentBookmarksPreview() {
|
|||
),
|
||||
),
|
||||
menuItems = listOf(),
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.mozilla.fenix.R
|
|||
import org.mozilla.fenix.components.components
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.home.recentbookmarks.interactor.RecentBookmarksInteractor
|
||||
import org.mozilla.fenix.wallpapers.WallpaperState
|
||||
import org.mozilla.fenix.GleanMetrics.RecentBookmarks as RecentBookmarksMetrics
|
||||
|
||||
class RecentBookmarksViewHolder(
|
||||
|
@ -33,11 +34,13 @@ class RecentBookmarksViewHolder(
|
|||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val recentBookmarks = components.appStore
|
||||
.observeAsComposableState { state -> state.recentBookmarks }
|
||||
val recentBookmarks = components.appStore.observeAsComposableState { state -> state.recentBookmarks }
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
|
||||
RecentBookmarks(
|
||||
bookmarks = recentBookmarks.value ?: emptyList(),
|
||||
backgroundColor = wallpaperState.wallpaperCardColor,
|
||||
onRecentBookmarkClick = interactor::onRecentBookmarkClicked,
|
||||
menuItems = listOf(
|
||||
RecentBookmarksMenuItem(
|
||||
|
|
|
@ -34,6 +34,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
@ -57,16 +58,22 @@ import org.mozilla.fenix.theme.Theme
|
|||
* A recent synced tab card.
|
||||
*
|
||||
* @param tab The [RecentSyncedTab] to display.
|
||||
* @param backgroundColor The background [Color] of the item.
|
||||
* @param buttonBackgroundColor The background [Color] of the item's button.
|
||||
* @param buttonTextColor The [Color] of the button's text.
|
||||
* @param onRecentSyncedTabClick Invoked when the user clicks on the recent synced tab.
|
||||
* @param onSeeAllSyncedTabsButtonClick Invoked when user clicks on the "See all" button in the synced tab card.
|
||||
* @param onRemoveSyncedTab Invoked when user clicks on the "Remove" dropdown menu option.
|
||||
* @param onRecentSyncedTabLongClick Invoked when user long presses the recent synced tab.
|
||||
*/
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "LongParameterList")
|
||||
@Composable
|
||||
fun RecentSyncedTab(
|
||||
tab: RecentSyncedTab?,
|
||||
backgroundColor: Color = FirefoxTheme.colors.layer2,
|
||||
buttonBackgroundColor: Color = FirefoxTheme.colors.actionSecondary,
|
||||
buttonTextColor: Color = FirefoxTheme.colors.textActionSecondary,
|
||||
onRecentSyncedTabClick: (RecentSyncedTab) -> Unit,
|
||||
onSeeAllSyncedTabsButtonClick: () -> Unit,
|
||||
onRemoveSyncedTab: (RecentSyncedTab) -> Unit,
|
||||
|
@ -91,7 +98,7 @@ fun RecentSyncedTab(
|
|||
},
|
||||
),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
backgroundColor = backgroundColor,
|
||||
elevation = 6.dp,
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
|
@ -178,12 +185,8 @@ fun RecentSyncedTab(
|
|||
} else {
|
||||
""
|
||||
},
|
||||
textColor = FirefoxTheme.colors.textActionSecondary,
|
||||
backgroundColor = if (tab == null) {
|
||||
FirefoxTheme.colors.layer3
|
||||
} else {
|
||||
FirefoxTheme.colors.actionSecondary
|
||||
},
|
||||
textColor = buttonTextColor,
|
||||
backgroundColor = buttonBackgroundColor,
|
||||
tint = FirefoxTheme.colors.iconActionSecondary,
|
||||
onClick = onSeeAllSyncedTabsButtonClick,
|
||||
)
|
||||
|
@ -302,6 +305,7 @@ private fun LoadingRecentSyncedTab() {
|
|||
FirefoxTheme(theme = Theme.getTheme()) {
|
||||
RecentSyncedTab(
|
||||
tab = null,
|
||||
buttonBackgroundColor = FirefoxTheme.colors.layer3,
|
||||
onRecentSyncedTabClick = {},
|
||||
onSeeAllSyncedTabsButtonClick = {},
|
||||
onRemoveSyncedTab = {},
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package org.mozilla.fenix.home.recentsyncedtabs.view
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
@ -14,6 +15,9 @@ 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
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.wallpapers.Wallpaper
|
||||
import org.mozilla.fenix.wallpapers.WallpaperState
|
||||
|
||||
/**
|
||||
* View holder for a recent synced tab item.
|
||||
|
@ -42,8 +46,11 @@ class RecentSyncedTabViewHolder(
|
|||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val recentSyncedTabState =
|
||||
components.appStore.observeAsComposableState { state -> state.recentSyncedTabState }
|
||||
val recentSyncedTabState = components.appStore.observeAsComposableState { state -> state.recentSyncedTabState }
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
val isWallpaperNotDefault = !Wallpaper.nameIsDefault(wallpaperState.currentWallpaper.name)
|
||||
|
||||
recentSyncedTabState.value?.let {
|
||||
val syncedTab = when (it) {
|
||||
RecentSyncedTabState.None,
|
||||
|
@ -51,8 +58,22 @@ class RecentSyncedTabViewHolder(
|
|||
-> null
|
||||
is RecentSyncedTabState.Success -> it.tabs.firstOrNull()
|
||||
}
|
||||
val buttonBackgroundColor = when {
|
||||
syncedTab != null && isWallpaperNotDefault -> FirefoxTheme.colors.layer1
|
||||
syncedTab != null -> FirefoxTheme.colors.actionSecondary
|
||||
else -> FirefoxTheme.colors.layer3
|
||||
}
|
||||
val buttonTextColor = when {
|
||||
wallpaperState.currentWallpaper.cardColorDark != null &&
|
||||
isSystemInDarkTheme() -> FirefoxTheme.colors.textPrimary
|
||||
else -> FirefoxTheme.colors.textActionSecondary
|
||||
}
|
||||
|
||||
RecentSyncedTab(
|
||||
tab = syncedTab,
|
||||
backgroundColor = wallpaperState.wallpaperCardColor,
|
||||
buttonBackgroundColor = buttonBackgroundColor,
|
||||
buttonTextColor = buttonTextColor,
|
||||
onRecentSyncedTabClick = recentSyncedTabInteractor::onRecentSyncedTabClicked,
|
||||
onSeeAllSyncedTabsButtonClick = recentSyncedTabInteractor::onSyncedTabShowAllClicked,
|
||||
onRemoveSyncedTab = recentSyncedTabInteractor::onRemovedRecentSyncedTab,
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.mozilla.fenix.R
|
|||
import org.mozilla.fenix.components.components
|
||||
import org.mozilla.fenix.compose.ComposeViewHolder
|
||||
import org.mozilla.fenix.home.recenttabs.interactor.RecentTabInteractor
|
||||
import org.mozilla.fenix.wallpapers.WallpaperState
|
||||
|
||||
/**
|
||||
* View holder for a recent tab item.
|
||||
|
@ -42,9 +43,12 @@ class RecentTabViewHolder(
|
|||
@Composable
|
||||
override fun Content() {
|
||||
val recentTabs = components.appStore.observeAsComposableState { state -> state.recentTabs }
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
|
||||
RecentTabs(
|
||||
recentTabs = recentTabs.value ?: emptyList(),
|
||||
backgroundColor = wallpaperState.wallpaperCardColor,
|
||||
onRecentTabClick = { recentTabInteractor.onRecentTabClicked(it) },
|
||||
onRecentTabLongClick = { recentTabInteractor.onRecentTabLongClicked() },
|
||||
menuItems = listOf(
|
||||
|
|
|
@ -39,6 +39,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
|
@ -66,12 +67,14 @@ import org.mozilla.fenix.theme.FirefoxTheme
|
|||
*
|
||||
* @param recentTabs List of [RecentTab] to display.
|
||||
* @param menuItems List of [RecentTabMenuItem] shown long clicking a [RecentTab].
|
||||
* @param backgroundColor The background [Color] of each item.
|
||||
* @param onRecentTabClick Invoked when the user clicks on a recent tab.
|
||||
*/
|
||||
@Composable
|
||||
fun RecentTabs(
|
||||
recentTabs: List<RecentTab>,
|
||||
menuItems: List<RecentTabMenuItem>,
|
||||
backgroundColor: Color = FirefoxTheme.colors.layer2,
|
||||
onRecentTabClick: (String) -> Unit = {},
|
||||
onRecentTabLongClick: () -> Unit = {},
|
||||
) {
|
||||
|
@ -85,6 +88,7 @@ fun RecentTabs(
|
|||
RecentTabItem(
|
||||
tab = tab,
|
||||
menuItems = menuItems,
|
||||
backgroundColor = backgroundColor,
|
||||
onRecentTabClick = onRecentTabClick,
|
||||
onRecentTabLongClick = onRecentTabLongClick,
|
||||
)
|
||||
|
@ -98,6 +102,7 @@ fun RecentTabs(
|
|||
* A recent tab item.
|
||||
*
|
||||
* @param tab [RecentTab.Tab] that was recently viewed.
|
||||
* @param backgroundColor The background [Color] of the item.
|
||||
* @param onRecentTabClick Invoked when the user clicks on a recent tab.
|
||||
*/
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
@ -105,6 +110,7 @@ fun RecentTabs(
|
|||
private fun RecentTabItem(
|
||||
tab: RecentTab.Tab,
|
||||
menuItems: List<RecentTabMenuItem>,
|
||||
backgroundColor: Color,
|
||||
onRecentTabClick: (String) -> Unit = {},
|
||||
onRecentTabLongClick: () -> Unit = {},
|
||||
) {
|
||||
|
@ -123,7 +129,7 @@ private fun RecentTabItem(
|
|||
},
|
||||
),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
backgroundColor = backgroundColor,
|
||||
elevation = 6.dp,
|
||||
) {
|
||||
Row(
|
||||
|
|
|
@ -39,6 +39,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
@ -64,6 +65,7 @@ private const val VISITS_PER_COLUMN = 3
|
|||
*
|
||||
* @param recentVisits List of [RecentlyVisitedItem] to display.
|
||||
* @param menuItems List of [RecentVisitMenuItem] shown long clicking a [RecentlyVisitedItem].
|
||||
* @param backgroundColor The background [Color] of each item.
|
||||
* @param onRecentVisitClick Invoked when the user clicks on a recent visit.
|
||||
* @param onRecentVisitLongClick Invoked when the user long clicks on a recent visit.
|
||||
*/
|
||||
|
@ -71,13 +73,14 @@ private const val VISITS_PER_COLUMN = 3
|
|||
fun RecentlyVisited(
|
||||
recentVisits: List<RecentlyVisitedItem>,
|
||||
menuItems: List<RecentVisitMenuItem>,
|
||||
backgroundColor: Color = FirefoxTheme.colors.layer2,
|
||||
onRecentVisitClick: (RecentlyVisitedItem, Int) -> Unit = { _, _ -> },
|
||||
onRecentVisitLongClick: () -> Unit = {},
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
backgroundColor = backgroundColor,
|
||||
elevation = 6.dp,
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
|
|
|
@ -20,6 +20,7 @@ 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.wallpapers.WallpaperState
|
||||
|
||||
/**
|
||||
* View holder for [RecentlyVisitedItem]s.
|
||||
|
@ -43,6 +44,8 @@ class RecentlyVisitedViewHolder(
|
|||
override fun Content() {
|
||||
val recentVisits = components.appStore
|
||||
.observeAsComposableState { state -> state.recentHistory }
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
|
||||
RecentlyVisited(
|
||||
recentVisits = recentVisits.value ?: emptyList(),
|
||||
|
@ -59,6 +62,7 @@ class RecentlyVisitedViewHolder(
|
|||
},
|
||||
),
|
||||
),
|
||||
backgroundColor = wallpaperState.wallpaperCardColor,
|
||||
onRecentVisitClick = { recentlyVisitedItem, pageNumber ->
|
||||
when (recentlyVisitedItem) {
|
||||
is RecentHistoryHighlight -> {
|
||||
|
|
|
@ -309,6 +309,7 @@ class SessionControlAdapter(
|
|||
TopPlaceholderViewHolder.LAYOUT_ID -> TopPlaceholderViewHolder(view)
|
||||
TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(
|
||||
view = view,
|
||||
store = components.appStore,
|
||||
viewLifecycleOwner = viewLifecycleOwner,
|
||||
interactor = interactor,
|
||||
)
|
||||
|
|
|
@ -5,19 +5,27 @@
|
|||
package org.mozilla.fenix.home.sessioncontrol.viewholders
|
||||
|
||||
import android.view.View
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
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.graphics.Color
|
||||
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.compose.button.Button
|
||||
import org.mozilla.fenix.compose.button.TertiaryButton
|
||||
import org.mozilla.fenix.home.sessioncontrol.CustomizeHomeIteractor
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
import org.mozilla.fenix.wallpapers.Wallpaper
|
||||
import org.mozilla.fenix.wallpapers.WallpaperState
|
||||
|
||||
class CustomizeHomeButtonViewHolder(
|
||||
composeView: ComposeView,
|
||||
|
@ -37,11 +45,31 @@ class CustomizeHomeButtonViewHolder(
|
|||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val wallpaperState = components.appStore
|
||||
.observeAsComposableState { state -> state.wallpaperState }.value ?: WallpaperState.default
|
||||
var buttonColor: Color = FirefoxTheme.colors.actionTertiary
|
||||
val textColor: Color = FirefoxTheme.colors.textActionTertiary
|
||||
|
||||
wallpaperState.composeRunIfWallpaperCardColorsAreAvailable { cardColorLight, cardColorDark ->
|
||||
buttonColor = if (isSystemInDarkTheme()) {
|
||||
cardColorDark
|
||||
} else {
|
||||
cardColorLight
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(68.dp))
|
||||
|
||||
TertiaryButton(
|
||||
/**
|
||||
* This button will be stylized as a [TertiaryButton] when no wallpaper is selected.
|
||||
* Otherwise, the background will use [Wallpaper.cardColorLight] or [Wallpaper.cardColorDark].
|
||||
* */
|
||||
Button(
|
||||
text = stringResource(R.string.browser_menu_customize_home_1),
|
||||
textColor = textColor,
|
||||
backgroundColor = buttonColor,
|
||||
tint = FirefoxTheme.colors.iconActionTertiary,
|
||||
onClick = interactor::openCustomizeHomePage,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -10,28 +10,36 @@ import android.view.View
|
|||
import android.widget.PopupWindow
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import mozilla.components.feature.top.sites.TopSite
|
||||
import mozilla.components.lib.state.ext.flowScoped
|
||||
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
||||
import org.mozilla.fenix.GleanMetrics.Pings
|
||||
import org.mozilla.fenix.GleanMetrics.TopSites
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.databinding.TopSiteItemBinding
|
||||
import org.mozilla.fenix.ext.bitmapForUrl
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.isSystemInDarkTheme
|
||||
import org.mozilla.fenix.ext.loadIntoView
|
||||
import org.mozilla.fenix.ext.name
|
||||
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import org.mozilla.fenix.utils.view.ViewHolder
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
class TopSiteItemViewHolder(
|
||||
view: View,
|
||||
store: AppStore,
|
||||
private val viewLifecycleOwner: LifecycleOwner,
|
||||
private val interactor: TopSiteInteractor,
|
||||
) : ViewHolder(view) {
|
||||
|
@ -63,12 +71,30 @@ class TopSiteItemViewHolder(
|
|||
}
|
||||
val menu = topSiteMenu.menuBuilder.build(view.context).show(anchor = it)
|
||||
|
||||
it.setOnTouchListener @SuppressLint("ClickableViewAccessibility") { v, event ->
|
||||
it.setOnTouchListener { v, event ->
|
||||
onTouchEvent(v, event, menu)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
store.flowScoped(viewLifecycleOwner) { flow ->
|
||||
flow.map { state -> state.wallpaperState }
|
||||
.ifChanged()
|
||||
.collect { currentState ->
|
||||
var backgroundColor = ContextCompat.getColor(view.context, R.color.fx_mobile_layer_color_2)
|
||||
|
||||
currentState.runIfWallpaperCardColorsAreAvailable { cardColorLight, cardColorDark ->
|
||||
backgroundColor = if (view.context.isSystemInDarkTheme()) {
|
||||
cardColorDark
|
||||
} else {
|
||||
cardColorLight
|
||||
}
|
||||
}
|
||||
|
||||
binding.topSiteCard.setCardBackgroundColor(backgroundColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(topSite: TopSite, position: Int) {
|
||||
|
@ -140,6 +166,7 @@ class TopSiteItemViewHolder(
|
|||
Pings.topsitesImpression.submit()
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun onTouchEvent(
|
||||
v: View,
|
||||
event: MotionEvent,
|
||||
|
|
|
@ -12,18 +12,20 @@ import androidx.viewpager2.widget.ViewPager2
|
|||
import mozilla.components.feature.top.sites.TopSite
|
||||
import org.mozilla.fenix.GleanMetrics.TopSites
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.databinding.ComponentTopSitesPagerBinding
|
||||
import org.mozilla.fenix.home.sessioncontrol.AdapterItem
|
||||
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
|
||||
|
||||
class TopSitePagerViewHolder(
|
||||
view: View,
|
||||
store: AppStore,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
interactor: TopSiteInteractor,
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
private val binding = ComponentTopSitesPagerBinding.bind(view)
|
||||
private val topSitesPagerAdapter = TopSitesPagerAdapter(viewLifecycleOwner, interactor)
|
||||
private val topSitesPagerAdapter = TopSitesPagerAdapter(store, viewLifecycleOwner, interactor)
|
||||
private val pageIndicator = binding.pageIndicator
|
||||
private var currentPage = 0
|
||||
|
||||
|
|
|
@ -9,17 +9,19 @@ import androidx.lifecycle.LifecycleOwner
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import mozilla.components.feature.top.sites.TopSite
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.databinding.ComponentTopSitesBinding
|
||||
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
|
||||
import org.mozilla.fenix.utils.AccessibilityGridLayoutManager
|
||||
|
||||
class TopSiteViewHolder(
|
||||
view: View,
|
||||
store: AppStore,
|
||||
viewLifecycleOwner: LifecycleOwner,
|
||||
interactor: TopSiteInteractor,
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
private val topSitesAdapter = TopSitesAdapter(viewLifecycleOwner, interactor)
|
||||
private val topSitesAdapter = TopSitesAdapter(store, viewLifecycleOwner, interactor)
|
||||
val binding = ComponentTopSitesBinding.bind(view)
|
||||
|
||||
init {
|
||||
|
|
|
@ -10,17 +10,19 @@ import androidx.lifecycle.LifecycleOwner
|
|||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import mozilla.components.feature.top.sites.TopSite
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
|
||||
import org.mozilla.fenix.perf.StartupTimeline
|
||||
|
||||
class TopSitesAdapter(
|
||||
private val store: AppStore,
|
||||
private val viewLifecycleOwner: LifecycleOwner,
|
||||
private val interactor: TopSiteInteractor,
|
||||
) : ListAdapter<TopSite, TopSiteItemViewHolder>(TopSitesDiffCallback) {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopSiteItemViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(TopSiteItemViewHolder.LAYOUT_ID, parent, false)
|
||||
return TopSiteItemViewHolder(view, viewLifecycleOwner, interactor)
|
||||
return TopSiteItemViewHolder(view, store, viewLifecycleOwner, interactor)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TopSiteItemViewHolder, position: Int) {
|
||||
|
|
|
@ -11,11 +11,13 @@ import androidx.lifecycle.LifecycleOwner
|
|||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import mozilla.components.feature.top.sites.TopSite
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload
|
||||
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
|
||||
import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder.Companion.TOP_SITES_PER_PAGE
|
||||
|
||||
class TopSitesPagerAdapter(
|
||||
private val store: AppStore,
|
||||
private val viewLifecycleOwner: LifecycleOwner,
|
||||
private val interactor: TopSiteInteractor,
|
||||
) : ListAdapter<List<TopSite>, TopSiteViewHolder>(TopSiteListDiffCallback) {
|
||||
|
@ -23,7 +25,7 @@ class TopSitesPagerAdapter(
|
|||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopSiteViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(TopSiteViewHolder.LAYOUT_ID, parent, false)
|
||||
return TopSiteViewHolder(view, viewLifecycleOwner, interactor)
|
||||
return TopSiteViewHolder(view, store, viewLifecycleOwner, interactor)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
package org.mozilla.fenix.wallpapers
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
/**
|
||||
* Represents all state related to the Wallpapers feature.
|
||||
*
|
||||
|
@ -20,4 +25,44 @@ data class WallpaperState(
|
|||
availableWallpapers = listOf(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper property used to obtain the [Color] to fill-in cards in front of a wallpaper.
|
||||
*
|
||||
* @return The appropriate light or dark wallpaper card [Color], if available, otherwise a default.
|
||||
*/
|
||||
val wallpaperCardColor: Color
|
||||
@Composable get() = when {
|
||||
currentWallpaper.cardColorLight != null && currentWallpaper.cardColorDark != null -> {
|
||||
if (isSystemInDarkTheme()) {
|
||||
Color(currentWallpaper.cardColorDark)
|
||||
} else {
|
||||
Color(currentWallpaper.cardColorLight)
|
||||
}
|
||||
}
|
||||
else -> FirefoxTheme.colors.layer2
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the Composable [run] block only if the current wallpaper's card colors are available.
|
||||
*/
|
||||
@Composable
|
||||
fun composeRunIfWallpaperCardColorsAreAvailable(
|
||||
run: @Composable (cardColorLight: Color, cardColorDark: Color) -> Unit,
|
||||
) {
|
||||
if (currentWallpaper.cardColorLight != null && currentWallpaper.cardColorDark != null) {
|
||||
run(Color(currentWallpaper.cardColorLight), Color(currentWallpaper.cardColorDark))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the [run] block only if the current wallpaper's card colors are available.
|
||||
*/
|
||||
fun runIfWallpaperCardColorsAreAvailable(
|
||||
run: (cardColorLight: Int, cardColorDark: Int) -> Unit,
|
||||
) {
|
||||
if (currentWallpaper.cardColorLight != null && currentWallpaper.cardColorDark != null) {
|
||||
run(currentWallpaper.cardColorLight.toInt(), currentWallpaper.cardColorDark.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
android:focusable="true">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/top_site_card"
|
||||
style="@style/TopSite.Card">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
|
|
@ -682,7 +682,6 @@
|
|||
<item name="android:layout_gravity">center_horizontal</item>
|
||||
<item name="android:importantForAccessibility">noHideDescendants</item>
|
||||
<item name="contentPadding">@dimen/top_sites_card_padding</item>
|
||||
<item name="cardBackgroundColor">?mozac_widget_favicon_background_color</item>
|
||||
<item name="cardCornerRadius">@dimen/top_sites_card_radius</item>
|
||||
<item name="cardElevation">@dimen/top_sites_card_elevation</item>
|
||||
</style>
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.GleanMetrics.Pings
|
||||
import org.mozilla.fenix.GleanMetrics.TopSites
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.databinding.TopSiteItemBinding
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
@ -37,6 +38,7 @@ class TopSiteItemViewHolderTest {
|
|||
private lateinit var binding: TopSiteItemBinding
|
||||
private lateinit var interactor: TopSiteInteractor
|
||||
private lateinit var lifecycleOwner: LifecycleOwner
|
||||
private lateinit var store: AppStore
|
||||
|
||||
private val pocket = TopSite.Default(
|
||||
id = 1L,
|
||||
|
@ -50,13 +52,14 @@ class TopSiteItemViewHolderTest {
|
|||
binding = TopSiteItemBinding.inflate(LayoutInflater.from(testContext))
|
||||
interactor = mockk(relaxed = true)
|
||||
lifecycleOwner = mockk(relaxed = true)
|
||||
store = mockk(relaxed = true)
|
||||
|
||||
every { testContext.components.core.icons } returns BrowserIcons(testContext, mockk(relaxed = true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `calls interactor on click`() {
|
||||
TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(pocket, position = 0)
|
||||
TopSiteItemViewHolder(binding.root, store, lifecycleOwner, interactor).bind(pocket, position = 0)
|
||||
|
||||
binding.root.performClick()
|
||||
verify { interactor.onSelectTopSite(pocket, position = 0) }
|
||||
|
@ -65,7 +68,7 @@ class TopSiteItemViewHolderTest {
|
|||
@Test
|
||||
fun `calls interactor on long click`() {
|
||||
every { testContext.components.analytics } returns mockk(relaxed = true)
|
||||
TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(pocket, position = 0)
|
||||
TopSiteItemViewHolder(binding.root, store, lifecycleOwner, interactor).bind(pocket, position = 0)
|
||||
|
||||
binding.root.performLongClick()
|
||||
verify { interactor.onTopSiteMenuOpened() }
|
||||
|
@ -80,7 +83,7 @@ class TopSiteItemViewHolderTest {
|
|||
createdAt = 0,
|
||||
)
|
||||
|
||||
TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(defaultTopSite, position = 0)
|
||||
TopSiteItemViewHolder(binding.root, store, lifecycleOwner, interactor).bind(defaultTopSite, position = 0)
|
||||
val pinIndicator = binding.topSiteTitle.compoundDrawables[0]
|
||||
|
||||
assertNotNull(pinIndicator)
|
||||
|
@ -95,7 +98,7 @@ class TopSiteItemViewHolderTest {
|
|||
createdAt = 0,
|
||||
)
|
||||
|
||||
TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(pinnedTopSite, position = 0)
|
||||
TopSiteItemViewHolder(binding.root, store, lifecycleOwner, interactor).bind(pinnedTopSite, position = 0)
|
||||
val pinIndicator = binding.topSiteTitle.compoundDrawables[0]
|
||||
|
||||
assertNotNull(pinIndicator)
|
||||
|
@ -110,7 +113,7 @@ class TopSiteItemViewHolderTest {
|
|||
createdAt = 0,
|
||||
)
|
||||
|
||||
TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(frecentTopSite, position = 0)
|
||||
TopSiteItemViewHolder(binding.root, store, lifecycleOwner, interactor).bind(frecentTopSite, position = 0)
|
||||
val pinIndicator = binding.topSiteTitle.compoundDrawables[0]
|
||||
|
||||
assertNull(pinIndicator)
|
||||
|
@ -144,7 +147,7 @@ class TopSiteItemViewHolderTest {
|
|||
topSiteImpressionSubmitted = true
|
||||
}
|
||||
|
||||
TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).submitTopSitesImpressionPing(topSite, position)
|
||||
TopSiteItemViewHolder(binding.root, store, lifecycleOwner, interactor).submitTopSitesImpressionPing(topSite, position)
|
||||
|
||||
assertNotNull(TopSites.contileImpression.testGetValue())
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.databinding.ComponentTopSitesBinding
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
|
||||
|
@ -23,17 +24,19 @@ class TopSiteViewHolderTest {
|
|||
private lateinit var binding: ComponentTopSitesBinding
|
||||
private lateinit var lifecycleOwner: LifecycleOwner
|
||||
private lateinit var interactor: TopSiteInteractor
|
||||
private lateinit var store: AppStore
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
binding = ComponentTopSitesBinding.inflate(LayoutInflater.from(testContext))
|
||||
interactor = mockk(relaxed = true)
|
||||
lifecycleOwner = mockk(relaxed = true)
|
||||
store = mockk(relaxed = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `binds list of top sites`() {
|
||||
TopSiteViewHolder(binding.root, lifecycleOwner, interactor).bind(
|
||||
TopSiteViewHolder(binding.root, store, lifecycleOwner, interactor).bind(
|
||||
listOf(
|
||||
TopSite.Default(
|
||||
id = 1L,
|
||||
|
|
|
@ -49,7 +49,7 @@ class TopSitesPagerAdapterTest {
|
|||
|
||||
@Before
|
||||
fun setup() {
|
||||
topSitesPagerAdapter = spyk(TopSitesPagerAdapter(mockk(), mockk()))
|
||||
topSitesPagerAdapter = spyk(TopSitesPagerAdapter(mockk(), mockk(), mockk()))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -53,7 +53,7 @@ class StartupReportFullyDrawnTest {
|
|||
holderItemView = spyk(binding.root)
|
||||
every { activity.findViewById<LinearLayout>(R.id.rootContainer) } returns rootContainer
|
||||
every { holderItemView.context } returns activity
|
||||
holder = TopSiteItemViewHolder(holderItemView, mockk(), mockk())
|
||||
holder = TopSiteItemViewHolder(holderItemView, mockk(), mockk(), mockk())
|
||||
every { rootContainer.viewTreeObserver } returns viewTreeObserver
|
||||
every { holderItemView.viewTreeObserver } returns viewTreeObserver
|
||||
|
||||
|
|
Loading…
Reference in New Issue