Add Micro Book Thumbnail.

This commit is contained in:
Thomas Andres Gomez 2022-07-19 16:23:02 +02:00
parent fb1709125d
commit c7dc9b227c
5 changed files with 226 additions and 4 deletions

View file

@ -0,0 +1,207 @@
package com.pixelized.biblib.ui.screen.home.common.item
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
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.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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.skydoves.landscapist.glide.GlideImage
@Stable
data class MicroBookThumbnailUio(
val id: Int,
val title: String,
val author: String,
val isNew: Boolean,
val cover: String,
)
@Composable
fun MicroBookThumbnail(
modifier: Modifier = Modifier,
thumbnail: MicroBookThumbnailUio?,
onClick: (MicroBookThumbnailUio) -> Unit = default<MicroBookThumbnailUio>(),
) {
if (thumbnail != null) {
MicroBookThumbnailContent(
modifier = modifier,
thumbnail = thumbnail,
onClick = onClick,
)
} else {
MicroBookThumbnailPlaceHolder(
modifier = modifier,
)
}
}
@Composable
private fun MicroBookThumbnailContent(
modifier: Modifier = Modifier,
thumbnail: MicroBookThumbnailUio,
onClick: (MicroBookThumbnailUio) -> Unit = default<MicroBookThumbnailUio>(),
) {
val dimen = MaterialTheme.bibLib.dimen
Card(
modifier = modifier
.clickable { onClick(thumbnail) }
.fillMaxWidth()
.wrapContentHeight(),
shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverSmall,
) {
ConstraintLayout(
modifier = Modifier.fillMaxWidth(),
) {
val (cover, title, author) = createRefs()
GlideImage(
modifier = Modifier
.constrainAs(cover) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
}
.clip(shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverSmall)
.size(size = MaterialTheme.bibLib.dimen.thumbnail.micro),
previewPlaceholder = R.drawable.ic_fondation_thumbnail,
imageModel = thumbnail.cover,
)
Text(
modifier = Modifier.constrainAs(title) {
top.linkTo(parent.top, margin = dimen.dp8)
start.linkTo(cover.end, margin = dimen.dp8)
end.linkTo(parent.end, margin = dimen.dp8)
width = Dimension.fillToConstraints
},
style = MaterialTheme.typography.body1,
color = MaterialTheme.bibLib.colors.typography.medium,
text = thumbnail.title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
modifier = Modifier.constrainAs(author) {
top.linkTo(title.bottom, margin = dimen.dp4)
bottom.linkTo(parent.bottom, margin = dimen.dp4)
start.linkTo(cover.end, margin = dimen.dp8)
end.linkTo(parent.end, margin = dimen.dp8)
width = Dimension.fillToConstraints
height = Dimension.fillToConstraints
},
style = MaterialTheme.typography.caption,
color = MaterialTheme.bibLib.colors.typography.easy,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
text = thumbnail.author
)
}
}
}
@Composable
private fun MicroBookThumbnailPlaceHolder(
modifier: Modifier = Modifier,
) {
val dimen = MaterialTheme.bibLib.dimen
Card(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight(),
shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverSmall,
) {
ConstraintLayout(
modifier = Modifier.fillMaxWidth(),
) {
val (cover, title, author) = createRefs()
Box(
modifier = Modifier
.constrainAs(cover) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
}
.size(size = MaterialTheme.bibLib.dimen.thumbnail.micro)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = MaterialTheme.bibLib.shapes.bookThumbnailCoverSmall,
),
)
Box(
modifier = Modifier
.constrainAs(title) {
top.linkTo(parent.top, margin = dimen.dp8)
start.linkTo(cover.end, margin = dimen.dp8)
}
.size(width = 120.dp, height = 16.dp)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = CircleShape,
),
)
Box(
modifier = Modifier
.constrainAs(author) {
top.linkTo(title.bottom, margin = dimen.dp4)
start.linkTo(cover.end, margin = dimen.dp8)
}
.size(width = 100.dp, height = 16.dp)
.background(
color = MaterialTheme.bibLib.colors.placeHolder,
shape = CircleShape,
),
)
}
}
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun MicroBookThumbnailPreview() {
BibLibTheme {
MicroBookThumbnail(
thumbnail = MicroBookThumbnailUio(
id = 0,
title = "Foundation",
author = "Asimov",
isNew = false,
cover = "",
)
)
}
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun MicroBookThumbnailEmptyPreview() {
BibLibTheme {
MicroBookThumbnail(
thumbnail = null,
)
}
}

View file

@ -34,6 +34,8 @@ import com.pixelized.biblib.ui.scaffold.LocalCategorySearchBottomSheetState
import com.pixelized.biblib.ui.scaffold.LocalDetailBottomSheetState import com.pixelized.biblib.ui.scaffold.LocalDetailBottomSheetState
import com.pixelized.biblib.ui.scaffold.LocalSearchViewModel import com.pixelized.biblib.ui.scaffold.LocalSearchViewModel
import com.pixelized.biblib.ui.scaffold.SearchFilter import com.pixelized.biblib.ui.scaffold.SearchFilter
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnail
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnail import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnail
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme
@ -72,10 +74,10 @@ fun SearchPage(
@Composable @Composable
private fun SearchPageContent( private fun SearchPageContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
search: Flow<PagingData<SmallBookThumbnailUio>> = emptyFlow(), search: Flow<PagingData<MicroBookThumbnailUio>> = emptyFlow(),
filters: List<SearchFilter> = SearchFilter.all, filters: List<SearchFilter> = SearchFilter.all,
onFilter: (filter: SearchFilter) -> Unit = default<SearchFilter>(), onFilter: (filter: SearchFilter) -> Unit = default<SearchFilter>(),
onDetail: (item: SmallBookThumbnailUio) -> Unit = default<SmallBookThumbnailUio>() onDetail: (item: MicroBookThumbnailUio) -> Unit = default<MicroBookThumbnailUio>()
) { ) {
val items = search.collectAsLazyPagingItems() val items = search.collectAsLazyPagingItems()
@ -96,7 +98,7 @@ private fun SearchPageContent(
) )
} }
items(items = items, key = { it.id }) { item -> items(items = items, key = { it.id }) { item ->
SmallBookThumbnail( MicroBookThumbnail(
modifier = Modifier.padding(horizontal = MaterialTheme.bibLib.dimen.thumbnail.padding), modifier = Modifier.padding(horizontal = MaterialTheme.bibLib.dimen.thumbnail.padding),
thumbnail = item, thumbnail = item,
onClick = { onDetail(it) } onClick = { onDetail(it) }

View file

@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.* import androidx.paging.*
import com.pixelized.biblib.repository.book.IBookRepository import com.pixelized.biblib.repository.book.IBookRepository
import com.pixelized.biblib.utils.extention.toMicroThumbnailUio
import com.pixelized.biblib.utils.extention.toSmallThumbnailUio import com.pixelized.biblib.utils.extention.toSmallThumbnailUio
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -86,7 +87,7 @@ class SearchViewModel @Inject constructor(
.combine(language.confirmFlow) { paging, filter -> .combine(language.confirmFlow) { paging, filter ->
paging.filter { filter == null || it.language == null || it.language.id == filter.id } paging.filter { filter == null || it.language == null || it.language.id == filter.id }
} }
.map { paging -> paging.map { it.toSmallThumbnailUio() } } .map { paging -> paging.map { it.toMicroThumbnailUio() } }
data class FilterUio( data class FilterUio(
val id: Int, val id: Int,

View file

@ -36,6 +36,7 @@ data class BibLibDimen(
val padding: Dp = 16.dp, val padding: Dp = 16.dp,
val arrangement: Dp = 16.dp, val arrangement: Dp = 16.dp,
val cover: DpSize = DpSize(width = 72.dp, height = 115.dp), // ratio 1.6 val cover: DpSize = DpSize(width = 72.dp, height = 115.dp), // ratio 1.6
val micro: DpSize = DpSize(width = 40.dp, height = 64.dp), // ratio 1.6
) )
@Stable @Stable

View file

@ -4,6 +4,7 @@ import androidx.annotation.StringDef
import com.pixelized.biblib.model.book.Book import com.pixelized.biblib.model.book.Book
import com.pixelized.biblib.network.client.IBibLibClient import com.pixelized.biblib.network.client.IBibLibClient
import com.pixelized.biblib.ui.screen.home.common.item.LargeBookThumbnailUio import com.pixelized.biblib.ui.screen.home.common.item.LargeBookThumbnailUio
import com.pixelized.biblib.ui.screen.home.common.item.MicroBookThumbnailUio
import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio import com.pixelized.biblib.ui.screen.home.common.item.SmallBookThumbnailUio
import com.pixelized.biblib.ui.screen.home.detail.BookDetailUio import com.pixelized.biblib.ui.screen.home.detail.BookDetailUio
@ -15,6 +16,16 @@ import com.pixelized.biblib.ui.screen.home.detail.BookDetailUio
) )
annotation class CoverUrl annotation class CoverUrl
fun Book.toMicroThumbnailUio(
@CoverUrl coverBaseUrl: String = IBibLibClient.THUMBNAIL_URL
) = MicroBookThumbnailUio(
id = id,
title = title,
author = author.joinToString { it.name },
isNew = isNew,
cover = "${coverBaseUrl}/$id.jpg",
)
fun Book.toSmallThumbnailUio( fun Book.toSmallThumbnailUio(
@CoverUrl coverBaseUrl: String = IBibLibClient.THUMBNAIL_URL @CoverUrl coverBaseUrl: String = IBibLibClient.THUMBNAIL_URL
) = SmallBookThumbnailUio( ) = SmallBookThumbnailUio(