Add isNew ribbon

This commit is contained in:
Thomas Andres Gomez 2023-03-27 14:09:01 +02:00
parent 8be1ecc0a7
commit 74fed885d0
8 changed files with 190 additions and 124 deletions

View file

@ -1,33 +1,32 @@
package com.pixelized.biblib.ui.screen.home.common.item
import android.annotation.SuppressLint
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.pixelized.biblib.R
import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib
import com.pixelized.biblib.utils.extention.default
import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
import com.skydoves.landscapist.glide.GlideImage
@Stable
data class LargeBookThumbnailUio(
val id: Int,
val title: String,
val author: String,
val date: String?,
val isNew: Boolean,
val cover: String,
)
@ -64,98 +63,52 @@ private fun LargeBookThumbnailContent(
thumbnail: LargeBookThumbnailUio,
onClick: (LargeBookThumbnailUio) -> Unit = default<LargeBookThumbnailUio>(),
) {
Column(
modifier = modifier.clickable { thumbnail.let(onClick) }
) {
GlideImage(
modifier = Modifier
.clip(shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverLarge)
.fillMaxWidth()
.aspectRatio(64f / 102f),
previewPlaceholder = R.drawable.ic_fondatoin_cover,
imageModel = thumbnail.cover,
)
Text(
modifier = Modifier
.padding(top = MaterialTheme.bibLib.dimen.dp4)
.padding(horizontal = MaterialTheme.bibLib.dimen.dp8),
style = MaterialTheme.typography.body1,
color = MaterialTheme.bibLib.colors.typography.medium,
text = thumbnail.title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
modifier = Modifier.padding(horizontal = MaterialTheme.bibLib.dimen.dp8),
style = MaterialTheme.typography.caption,
color = MaterialTheme.bibLib.colors.typography.easy,
text = thumbnail.author
)
Text(
modifier = Modifier
.align(alignment = Alignment.End)
.padding(horizontal = MaterialTheme.bibLib.dimen.dp8)
.padding(bottom = MaterialTheme.bibLib.dimen.dp8),
style = MaterialTheme.typography.caption,
color = MaterialTheme.bibLib.colors.typography.easy,
text = thumbnail.date ?: ""
)
}
GlideImage(
modifier = Modifier
.clip(shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverLarge)
.fillMaxWidth()
.aspectRatio(64f / 102f)
.isNew { thumbnail.isNew }
.clickable { thumbnail.let(onClick) },
previewPlaceholder = R.drawable.ic_fondatoin_cover,
imageModel = thumbnail.cover,
)
}
@Composable
private fun LargeBookThumbnailPlaceHolder(
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
Box(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(64f / 102f)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverLarge,
),
)
Box(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(64f / 102f)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverLarge,
),
)
}
Box(
modifier = Modifier
.padding(top = MaterialTheme.bibLib.dimen.dp4)
.padding(horizontal = MaterialTheme.bibLib.dimen.dp8)
.size(width = 80.dp, height = 12.dp)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = CircleShape,
),
)
Box(
modifier = Modifier
.padding(top = MaterialTheme.bibLib.dimen.dp4)
.padding(horizontal = MaterialTheme.bibLib.dimen.dp8)
.size(width = 60.dp, height = 12.dp)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = CircleShape,
),
)
Box(
modifier = Modifier
.align(alignment = Alignment.End)
.padding(top = MaterialTheme.bibLib.dimen.dp4)
.padding(horizontal = MaterialTheme.bibLib.dimen.dp8)
.padding(bottom = MaterialTheme.bibLib.dimen.dp8)
.size(width = 40.dp, height = 12.dp)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = CircleShape,
),
)
@SuppressLint("ComposableModifierFactory")
@Composable
private fun Modifier.isNew(
isNew: () -> Boolean,
) = if (isNew()) {
val theme = MaterialTheme.bibLib
val label: String = stringResource(id = R.string.list_is_new)
val color: Color = Color.Red
val style: TextStyle = remember {
theme.typography.base.caption.copy(color = Color.White)
}
drawDiagonalLabel(
text = label,
color = color,
style = style,
labelTextRatio = 4f,
)
} else {
this
}
@Composable
@ -167,10 +120,7 @@ private fun LargeBookThumbnailPreview() {
modifier = Modifier.width(168.dp),
thumbnail = LargeBookThumbnailUio(
id = 0,
title = "Foundation",
author = "Asimov",
date = "February 1951",
isNew = false,
isNew = true,
cover = "",
),
)

View file

@ -1,5 +1,6 @@
package com.pixelized.biblib.ui.screen.home.common.item
import android.annotation.SuppressLint
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@ -13,17 +14,23 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import com.pixelized.biblib.R
import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib
import com.pixelized.biblib.utils.extention.default
import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
import com.skydoves.landscapist.glide.GlideImage
@Stable
@ -82,7 +89,8 @@ private fun MicroBookThumbnailContent(
start.linkTo(parent.start)
}
.clip(shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverSmall)
.size(size = MaterialTheme.bibLib.dimen.thumbnail.micro),
.size(size = MaterialTheme.bibLib.dimen.thumbnail.micro)
.isNew { thumbnail.isNew },
previewPlaceholder = R.drawable.ic_fondation_thumbnail,
imageModel = thumbnail.cover,
)
@ -191,6 +199,30 @@ private fun MicroBookThumbnailPlaceHolder(
}
}
@SuppressLint("ComposableModifierFactory")
@Composable
private fun Modifier.isNew(
isNew: () -> Boolean,
) = if (isNew()) {
val theme = MaterialTheme.bibLib
val label: String = stringResource(id = R.string.list_is_new)
val color: Color = Color.Red
val style: TextStyle = remember {
theme.typography.base.caption.copy(
color = Color.White,
fontSize = 8.sp,
)
}
drawDiagonalLabel(
text = label,
color = color,
style = style,
labelTextRatio = 2f,
)
} else {
this
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@ -203,7 +235,7 @@ private fun MicroBookThumbnailPreview() {
title = "Foundation",
author = "Asimov",
series = "Foundation - 1",
isNew = false,
isNew = true,
)
)
}

View file

@ -1,5 +1,6 @@
package com.pixelized.biblib.ui.screen.home.common.item
import android.annotation.SuppressLint
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@ -10,9 +11,13 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
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.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -22,6 +27,7 @@ import com.pixelized.biblib.R
import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib
import com.pixelized.biblib.utils.extention.default
import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
import com.skydoves.landscapist.glide.GlideImage
@Stable
@ -81,7 +87,8 @@ private fun SmallBookThumbnailContent(
start.linkTo(parent.start)
}
.clip(shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverSmall)
.size(size = MaterialTheme.bibLib.dimen.thumbnail.cover),
.size(size = MaterialTheme.bibLib.dimen.thumbnail.cover)
.isNew { thumbnail.isNew },
previewPlaceholder = R.drawable.ic_fondation_thumbnail,
imageModel = thumbnail.cover,
)
@ -228,6 +235,27 @@ private fun SmallBookThumbnailPlaceHolder(
}
}
@SuppressLint("ComposableModifierFactory")
@Composable
private fun Modifier.isNew(
isNew: () -> Boolean,
) = if (isNew()) {
val theme = MaterialTheme.bibLib
val label: String = stringResource(id = R.string.list_is_new)
val color: Color = Color.Red
val style: TextStyle = remember {
theme.typography.base.caption.copy(color = Color.White)
}
drawDiagonalLabel(
text = label,
color = color,
style = style,
labelTextRatio = 2f,
)
} else {
this
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@ -240,7 +268,7 @@ private fun SmallBookThumbnailPreview() {
title = "Foundation",
author = "Asimov",
date = "1951",
isNew = false,
isNew = true,
cover = "",
)
)

View file

@ -84,57 +84,36 @@ fun largeBookThumbnailPreviewResources(): LazyPagingItems<LargeBookThumbnailUio>
val thumbnails = listOf(
LargeBookThumbnailUio(
id = 112,
title = "Prélude à Fondation",
author = "Asimov",
date = "1988",
isNew = false,
cover = "",
),
LargeBookThumbnailUio(
id = 78,
title = "L'Aube de Fondation",
author = "Asimov",
date = "1993",
isNew = false,
cover = "",
),
LargeBookThumbnailUio(
id = 90,
title = "Fondation",
author = "Asimov",
date = "1951",
isNew = false,
cover = "",
),
LargeBookThumbnailUio(
id = 184,
title = "Fondation et Empire",
author = "Asimov",
date = "1952",
isNew = false,
cover = "",
),
LargeBookThumbnailUio(
id = 185,
title = "Seconde Fondation",
author = "Asimov",
date = "1953",
isNew = false,
cover = "",
),
LargeBookThumbnailUio(
id = 119,
title = "Fondation foudroyée",
author = "Asimov",
date = "1982",
isNew = false,
cover = "",
),
LargeBookThumbnailUio(
id = 163,
title = "Terre et Fondation",
author = "Asimov",
date = "1986",
isNew = false,
cover = "",
),

View file

@ -3,9 +3,10 @@ package com.pixelized.biblib.ui.theme.typography
import androidx.compose.material.Typography
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import java.time.format.TextStyle
@Stable
@Immutable
data class BibLibTypography(
val base: Typography = Typography()
val base: Typography = Typography(),
)

View file

@ -44,9 +44,6 @@ fun Book.toLargeBookThumbnailUio(
@CoverUrl coverBaseUrl: String = IBibLibClient.COVER_URL
) = LargeBookThumbnailUio(
id = id,
title = title,
author = author.joinToString { it.name },
date = releaseDate.longDate(),
isNew = isNew,
cover = "${coverBaseUrl}/$id.jpg",
)

View file

@ -0,0 +1,77 @@
package com.pixelized.biblib.utils.extention.modifier
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.text.*
import kotlin.math.sqrt
@OptIn(ExperimentalTextApi::class)
fun Modifier.drawDiagonalLabel(
text: String,
color: Color,
style: TextStyle,
labelTextRatio: Float,
) = clipToBounds().composed(
factory = {
val textMeasurer = rememberTextMeasurer()
val textLayoutResult: TextLayoutResult = remember {
textMeasurer.measure(text = AnnotatedString(text), style = style)
}
drawWithContent {
val canvasWidth = size.width
val textSize = textLayoutResult.size
val textWidth = textSize.width
val textHeight = textSize.height
val rectWidth = textWidth * labelTextRatio * 1.1f
val rect = Rect(
offset = Offset(canvasWidth - rectWidth, 0f),
size = Size(rectWidth, textHeight.toFloat())
)
val sqrt = sqrt(rectWidth / 2f)
val translatePos = sqrt * sqrt
drawContent()
withTransform(
transformBlock = {
rotate(
degrees = 45f,
pivot = Offset(
canvasWidth - rectWidth / 2,
translatePos
)
)
},
drawBlock = {
drawRect(
color = color,
topLeft = rect.topLeft,
size = rect.size
)
drawText(
textMeasurer = textMeasurer,
text = text,
style = style,
topLeft = Offset(
rect.left + (rectWidth - textWidth) / 2f,
rect.top + (rect.bottom - textHeight) / 2f
)
)
}
)
}
}
)

View file

@ -55,6 +55,8 @@
<string name="authentication_password">Password</string>
<string name="authentication_credential_remember">Remember my credential</string>
<string name="list_is_new" translatable="false">New</string>
<string name="detail_rating">Rating</string>
<string name="detail_language">Language</string>
<string name="detail_release">Release</string>