For #21888 - Use Hero images for Jump back in

This commit is contained in:
Gabriel Luong 2021-10-27 18:58:00 -04:00 committed by mergify[bot]
parent d0d87a6d6d
commit 09bd9e7ba2
2 changed files with 51 additions and 46 deletions

View File

@ -7,7 +7,10 @@ package org.mozilla.fenix.compose
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -27,6 +30,10 @@ import org.mozilla.fenix.components.components
* @param contentDescription Localized text used by accessibility services to describe what this image represents. * @param contentDescription Localized text used by accessibility services to describe what this image represents.
* This should always be provided unless this image is used for decorative purposes, and does not represent * This should always be provided unless this image is used for decorative purposes, and does not represent
* a meaningful action that a user can take. * a meaningful action that a user can take.
* @param alignment Optional alignment parameter used to place the [Painter] in the given
* bounds defined by the width and height.
* @param contentScale Optional scale parameter used to determine the aspect ratio scaling to be used
* if the bounds are a different size from the intrinsic size of the [Painter].
*/ */
@Composable @Composable
@Suppress("LongParameterList") @Suppress("LongParameterList")
@ -35,7 +42,9 @@ fun Image(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
private: Boolean = false, private: Boolean = false,
targetSize: Dp = 100.dp, targetSize: Dp = 100.dp,
contentDescription: String? = null contentDescription: String? = null,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
) { ) {
ImageLoader( ImageLoader(
url = url, url = url,
@ -48,6 +57,8 @@ fun Image(
painter = painter, painter = painter,
modifier = modifier, modifier = modifier,
contentDescription = contentDescription, contentDescription = contentDescription,
alignment = alignment,
contentScale = contentScale
) )
} }

View File

@ -32,12 +32,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -52,6 +52,7 @@ import mozilla.components.support.ktx.kotlin.getRepresentativeSnippet
import mozilla.components.ui.colors.PhotonColors import mozilla.components.ui.colors.PhotonColors
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.components import org.mozilla.fenix.components.components
import org.mozilla.fenix.compose.Image
import org.mozilla.fenix.home.recenttabs.RecentTab import org.mozilla.fenix.home.recenttabs.RecentTab
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
@ -76,14 +77,7 @@ fun RecentTabs(
when (tab) { when (tab) {
is RecentTab.Tab -> { is RecentTab.Tab -> {
RecentTabItem( RecentTabItem(
tabId = tab.state.id, tab = tab,
url = tab.state.content.url,
title = if (tab.state.content.title.isNotEmpty()) {
tab.state.content.title
} else {
tab.state.content.url
},
thumbnail = tab.state.content.thumbnail,
onRecentTabClick = onRecentTabClick onRecentTabClick = onRecentTabClick
) )
} }
@ -105,27 +99,20 @@ fun RecentTabs(
/** /**
* A recent tab item. * A recent tab item.
* *
* @param tabId The id of the tab. * @param tab [RecentTab.Tab] that was recently viewed.
* @param url The loaded URL of the tab.
* @param title The title of the tab.
* @param thumbnail The icon of the tab.
* @param onRecentTabClick Invoked when the user clicks on a recent tab. * @param onRecentTabClick Invoked when the user clicks on a recent tab.
*/ */
@Suppress("LongParameterList") @Suppress("LongParameterList")
@Composable @Composable
private fun RecentTabItem( private fun RecentTabItem(
tabId: String, tab: RecentTab.Tab,
url: String,
title: String,
icon: Bitmap? = null,
thumbnail: Bitmap? = null,
onRecentTabClick: (String) -> Unit = {} onRecentTabClick: (String) -> Unit = {}
) { ) {
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(112.dp) .height(112.dp)
.clickable { onRecentTabClick(tabId) }, .clickable { onRecentTabClick(tab.state.id) },
shape = RoundedCornerShape(8.dp), shape = RoundedCornerShape(8.dp),
backgroundColor = FirefoxTheme.colors.surface, backgroundColor = FirefoxTheme.colors.surface,
elevation = 6.dp elevation = 6.dp
@ -134,11 +121,10 @@ private fun RecentTabItem(
modifier = Modifier.padding(16.dp) modifier = Modifier.padding(16.dp)
) { ) {
RecentTabImage( RecentTabImage(
url = url, tab = tab,
tabId = tabId, modifier = Modifier
modifier = Modifier.size(108.dp, 80.dp) .size(108.dp, 80.dp)
.clip(RoundedCornerShape(8.dp)), .clip(RoundedCornerShape(8.dp))
thumbnail = thumbnail
) )
Spacer(modifier = Modifier.width(16.dp)) Spacer(modifier = Modifier.width(16.dp))
@ -147,19 +133,20 @@ private fun RecentTabItem(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween verticalArrangement = Arrangement.SpaceBetween
) { ) {
RecentTabTitle(title = title) RecentTabTitle(title = tab.state.content.title.ifEmpty { tab.state.content.url })
Row { Row {
RecentTabIcon( RecentTabIcon(
url = url, url = tab.state.content.url,
modifier = Modifier.size(18.dp, 18.dp) modifier = Modifier
.size(18.dp, 18.dp)
.clip(RoundedCornerShape(2.dp)), .clip(RoundedCornerShape(2.dp)),
icon = icon icon = tab.state.content.icon
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
RecentTabSubtitle(subtitle = url) RecentTabSubtitle(subtitle = tab.state.content.url)
} }
} }
} }
@ -230,25 +217,32 @@ private fun RecentSearchGroupItem(
/** /**
* A recent tab image. * A recent tab image.
* *
* @param url The loaded URL of the tab. * @param tab [RecentTab.Tab] that was recently viewed.
* @param modifier [Modifier] used to draw the image content. * @param modifier [Modifier] used to draw the image content.
* @param tabId The id of the tab.
* @param contentScale [ContentScale] used to draw image content. * @param contentScale [ContentScale] used to draw image content.
* @param alignment [Alignment] used to draw the image content. * @param alignment [Alignment] used to draw the image content.
* @param thumbnail The icon of the tab. Fallback to loading the icon from the [url] if the [thumbnail]
* is null. * is null.
*/ */
@Composable @Composable
@Suppress("LongParameterList") @Suppress("LongParameterList")
private fun RecentTabImage( private fun RecentTabImage(
url: String, tab: RecentTab.Tab,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
tabId: String? = null,
thumbnail: Bitmap? = null,
contentScale: ContentScale = ContentScale.FillWidth, contentScale: ContentScale = ContentScale.FillWidth,
alignment: Alignment = Alignment.TopCenter alignment: Alignment = Alignment.TopCenter
) { ) {
val previewImageUrl = tab.state.content.previewImageUrl
val thumbnail = tab.state.content.thumbnail
when { when {
!previewImageUrl.isNullOrEmpty() -> {
Image(
url = previewImageUrl,
modifier = modifier,
targetSize = 108.dp,
contentScale = ContentScale.Crop
)
}
thumbnail != null -> { thumbnail != null -> {
Image( Image(
painter = BitmapPainter(thumbnail.asImageBitmap()), painter = BitmapPainter(thumbnail.asImageBitmap()),
@ -263,7 +257,7 @@ private fun RecentTabImage(
modifier = modifier, modifier = modifier,
backgroundColor = colorResource(id = R.color.photonGrey20) backgroundColor = colorResource(id = R.color.photonGrey20)
) { ) {
components.core.icons.Loader(url) { components.core.icons.Loader(tab.state.content.url) {
Placeholder { Placeholder {
Box( Box(
modifier = Modifier.background( modifier = Modifier.background(
@ -283,21 +277,21 @@ private fun RecentTabImage(
Image( Image(
painter = icon.painter, painter = icon.painter,
contentDescription = null, contentDescription = null,
modifier = Modifier.size(36.dp).clip(RoundedCornerShape(8.dp)), modifier = Modifier
.size(36.dp)
.clip(RoundedCornerShape(8.dp)),
contentScale = ContentScale.Fit contentScale = ContentScale.Fit
) )
} }
} }
} }
if (tabId != null) { ThumbnailImage(
ThumbnailImage( tabId = tab.state.id,
tabId = tabId, modifier = modifier,
modifier = modifier, contentScale = contentScale,
contentScale = contentScale, alignment = alignment
alignment = alignment )
)
}
} }
} }
} }