For #21888 - Use Hero images for Jump back in
This commit is contained in:
parent
d0d87a6d6d
commit
09bd9e7ba2
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user