Filter by author / series from the detail feature.

This commit is contained in:
Thomas Andres Gomez 2023-03-31 12:54:22 +02:00
parent 8c264042d0
commit 100f8d32bd
8 changed files with 85 additions and 17 deletions

View file

@ -20,6 +20,8 @@ val LocalDetailBottomSheetState = staticCompositionLocalOf<DetailBottomSheetStat
@Composable @Composable
fun DetailBottomSheet( fun DetailBottomSheet(
bottomDetailState: DetailBottomSheetState = rememberDetailBottomSheetState(), bottomDetailState: DetailBottomSheetState = rememberDetailBottomSheetState(),
onAuthor: (String?, Int?) -> Unit,
onSeries: (String?, Int?) -> Unit,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@ -31,7 +33,11 @@ fun DetailBottomSheet(
scrimColor = ShadowPalette.scrim, scrimColor = ShadowPalette.scrim,
sheetState = bottomDetailState.bottomSheetState, sheetState = bottomDetailState.bottomSheetState,
sheetContent = { sheetContent = {
DetailScreen(bookId = bottomDetailState.bookId) DetailScreen(
bookId = bottomDetailState.bookId,
onAuthor = onAuthor,
onSeries = onSeries,
)
}, },
content = content, content = content,
) )

View file

@ -110,6 +110,36 @@ class BookSearchViewModel @Inject constructor(
searchSource?.invalidate() searchSource?.invalidate()
} }
fun cleanFilterThen(block: BookSearchViewModel.() -> Unit) {
// filter the search
_search.value = null
// clean the new filter
filterByNew = null
newFilter.value = newFilter.value.copy(selected = false)
// clean the author filter
filterByAuthorId = null
authorFilter.value = authorFilter.value.copy(
selected = false, label = null, closable = false, openable = true
)
// clean the author filter
filterBySeriesId = null
seriesFilter.value = seriesFilter.value.copy(
selected = false, label = null, closable = false, openable = true
)
// clean the author filter
filterByGenreId = null
genreFilter.value = genreFilter.value.copy(
selected = false, label = null, closable = false, openable = true
)
// clean the author filter
filterByLanguageId = null
languageFilter.value = languageFilter.value.copy(
selected = false, label = null, closable = false, openable = true
)
// call the filter
this.block()
}
fun filterSearch(criteria: String?) { fun filterSearch(criteria: String?) {
_search.value = criteria _search.value = criteria
searchSource?.invalidate() searchSource?.invalidate()

View file

@ -103,9 +103,23 @@ fun HomeScreen(
) { ) {
DetailBottomSheet( DetailBottomSheet(
bottomDetailState = detailState, bottomDetailState = detailState,
onAuthor = { label: String?, id: Int? ->
bookViewModel.cleanFilterThen {
filterByAuthor(label = label, criteria = id)
}
scope.launch { detailState.collapse() }
},
onSeries = { label: String?, id: Int? ->
bookViewModel.cleanFilterThen {
filterBySeries(label = label, criteria = id)
}
scope.launch { detailState.collapse() }
},
) { ) {
HomeScreenContent( HomeScreenContent(
modifier = Modifier.systemBarsPadding(), modifier = Modifier
.fillMaxSize()
.statusBarsPadding(),
avatar = profileViewModel.avatar, avatar = profileViewModel.avatar,
search = bookViewModel.search, search = bookViewModel.search,
onSearch = { onSearch = {
@ -514,9 +528,9 @@ private fun HomeToolbar(
TextField( TextField(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
placeholder = { label = {
Text( Text(
color = MaterialTheme.colors.onSurface, color = MaterialTheme.bibLib.colors.typography.medium,
text = stringResource(id = R.string.search_title), text = stringResource(id = R.string.search_title),
) )
}, },

View file

@ -19,7 +19,6 @@ import com.pixelized.biblib.ui.composable.scaffold.LocalDetailBottomSheetState
import com.pixelized.biblib.ui.screen.home.profile.ProfileViewModel import com.pixelized.biblib.ui.screen.home.profile.ProfileViewModel
import com.pixelized.biblib.ui.screen.home.profile.UserUio import com.pixelized.biblib.ui.screen.home.profile.UserUio
import com.pixelized.biblib.ui.theme.color.ShadowPalette import com.pixelized.biblib.ui.theme.color.ShadowPalette
import com.pixelized.biblib.utils.extention.bibLib
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Stable @Stable
@ -52,6 +51,8 @@ sealed class BookDetailUioErrorUio(
fun DetailScreen( fun DetailScreen(
detailViewModel: BookDetailViewModel = hiltViewModel(), detailViewModel: BookDetailViewModel = hiltViewModel(),
profileViewModel: ProfileViewModel = hiltViewModel(), profileViewModel: ProfileViewModel = hiltViewModel(),
onAuthor: (String?, Int?) -> Unit,
onSeries: (String?, Int?) -> Unit,
bookId: Int? = null, bookId: Int? = null,
) { ) {
val detailState = LocalDetailBottomSheetState.current val detailState = LocalDetailBottomSheetState.current
@ -96,6 +97,10 @@ fun DetailScreen(
.padding(all = 16.dp) .padding(all = 16.dp)
.systemBarsPadding(), .systemBarsPadding(),
book = detail, book = detail,
onAuthor = { onAuthor(detail.author, detail.authorId) },
onSeries = { onSeries(detail.series, detail.seriesId) },
onMobi = { },
onEpub = { },
onSend = { onSend = {
send( send(
context = context, context = context,

View file

@ -2,6 +2,7 @@ package com.pixelized.biblib.ui.screen.home.detail
import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -26,16 +27,12 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.core.text.toSpannable import androidx.core.text.toSpannable
import com.google.accompanist.placeholder.PlaceholderHighlight
import com.google.accompanist.placeholder.material.placeholder
import com.google.accompanist.placeholder.shimmer
import com.pixelized.biblib.R import com.pixelized.biblib.R
import com.pixelized.biblib.ui.composable.SpannedText import com.pixelized.biblib.ui.composable.SpannedText
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib import com.pixelized.biblib.utils.extention.bibLib
import com.pixelized.biblib.utils.extention.default
import com.pixelized.biblib.utils.extention.placeholder import com.pixelized.biblib.utils.extention.placeholder
import com.skydoves.landscapist.CircularReveal import com.skydoves.landscapist.CircularReveal
import com.skydoves.landscapist.glide.GlideImage import com.skydoves.landscapist.glide.GlideImage
@ -47,10 +44,12 @@ import java.io.Serializable
data class BookDetailUio( data class BookDetailUio(
val id: Int, val id: Int,
val title: String, val title: String,
val authorId: Int?,
val author: String, val author: String,
val rating: Float, val rating: Float,
val language: String, val language: String,
val date: String?, val date: String?,
val seriesId: Int?,
val series: String?, val series: String?,
val description: String, val description: String,
val cover: String, val cover: String,
@ -60,8 +59,10 @@ data class BookDetailUio(
fun preview() = BookDetailUio( fun preview() = BookDetailUio(
id = 90, id = 90,
title = "Foundation", title = "Foundation",
authorId = null,
author = "Asimov", author = "Asimov",
date = "1951", date = "1951",
seriesId = null,
series = "Foundation - 1", series = "Foundation - 1",
description = "En ce début de treizième millénaire, l'Empire n'a jamais été aussi puissant, aussi étendu à travers toute la galaxie. C'est dans sa capitale, Trantor, que l'éminent savant Hari Seldon invente la psychohistoire, une science nouvelle permettant de prédire l'avenir. Grâce à elle, Seldon prévoit l'effondrement de l'Empire d'ici cinq siècles, suivi d'une ère de ténèbres de trente mille ans. Réduire cette période à mille ans est peut-être possible, à condition de mener à terme son projet : la Fondation, chargée de rassembler toutes les connaissances humaines. Une entreprise visionnaire qui rencontre de nombreux et puissants détracteurs...", description = "En ce début de treizième millénaire, l'Empire n'a jamais été aussi puissant, aussi étendu à travers toute la galaxie. C'est dans sa capitale, Trantor, que l'éminent savant Hari Seldon invente la psychohistoire, une science nouvelle permettant de prédire l'avenir. Grâce à elle, Seldon prévoit l'effondrement de l'Empire d'ici cinq siècles, suivi d'une ère de ténèbres de trente mille ans. Réduire cette période à mille ans est peut-être possible, à condition de mener à terme son projet : la Fondation, chargée de rassembler toutes les connaissances humaines. Une entreprise visionnaire qui rencontre de nombreux et puissants détracteurs...",
rating = 4.5f, rating = 4.5f,
@ -76,9 +77,11 @@ data class BookDetailUio(
fun DetailScreenContent( fun DetailScreenContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
book: BookDetailUio, book: BookDetailUio,
onMobi: () -> Unit = default(), onAuthor: () -> Unit,
onEpub: () -> Unit = default(), onSeries: () -> Unit,
onSend: suspend () -> Unit = { }, onMobi: () -> Unit,
onEpub: () -> Unit,
onSend: suspend () -> Unit,
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@ -162,6 +165,7 @@ fun DetailScreenContent(
.padding(bottom = 16.dp), .padding(bottom = 16.dp),
) { ) {
Text( Text(
modifier = Modifier.clickable(onClick = onAuthor),
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.h6, style = MaterialTheme.typography.h6,
color = MaterialTheme.colors.onSurface, color = MaterialTheme.colors.onSurface,
@ -201,7 +205,9 @@ fun DetailScreenContent(
modifier = Modifier.padding(bottom = 16.dp), modifier = Modifier.padding(bottom = 16.dp),
) { ) {
TitleLabel( TitleLabel(
modifier = Modifier.fillMaxWidth(), modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onSeries),
title = stringResource(id = R.string.detail_series), title = stringResource(id = R.string.detail_series),
label = book.series ?: "-", label = book.series ?: "-",
) )
@ -262,6 +268,11 @@ private fun DetailScreenContentPreview() {
.verticalScroll(state = rememberScrollState()) .verticalScroll(state = rememberScrollState())
.padding(all = 16.dp), .padding(all = 16.dp),
book = BookDetailUio.preview(), book = BookDetailUio.preview(),
onAuthor = { },
onSeries = { },
onMobi = { },
onEpub = { },
onSend = { },
) )
} }
} }

View file

@ -110,7 +110,7 @@ fun DetailScreenSendOption(
.padding(vertical = 8.dp), .padding(vertical = 8.dp),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
style = MaterialTheme.typography.caption, style = MaterialTheme.typography.caption,
color = MaterialTheme.bibLib.colors.typography.dark, color = MaterialTheme.bibLib.colors.typography.emphasis,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
text = stringResource(R.string.detail_send_confirm_help), text = stringResource(R.string.detail_send_confirm_help),

View file

@ -20,7 +20,7 @@ data class BibLibColor(
data class Typography( data class Typography(
val light: Color, val light: Color,
val medium: Color, val medium: Color,
val dark: Color, val emphasis: Color,
) )
@Stable @Stable
@ -43,7 +43,7 @@ fun bibLibDarkColors(
typography: BibLibColor.Typography = BibLibColor.Typography( typography: BibLibColor.Typography = BibLibColor.Typography(
light = base.onSurface.copy(alpha = 0.67f), light = base.onSurface.copy(alpha = 0.67f),
medium = base.onSurface, medium = base.onSurface,
dark = base.primary, emphasis = base.primary,
), ),
placeHolder: BibLibColor.PlaceHolder = BibLibColor.PlaceHolder( placeHolder: BibLibColor.PlaceHolder = BibLibColor.PlaceHolder(
color = BibLibColorPalette.DarkGrey, color = BibLibColorPalette.DarkGrey,
@ -71,7 +71,7 @@ fun bibLibLightColors(
typography: BibLibColor.Typography = BibLibColor.Typography( typography: BibLibColor.Typography = BibLibColor.Typography(
light = base.onSurface.copy(alpha = 0.67f), light = base.onSurface.copy(alpha = 0.67f),
medium = base.onSurface, medium = base.onSurface,
dark = base.primary, emphasis = base.primary,
), ),
placeHolder: BibLibColor.PlaceHolder = BibLibColor.PlaceHolder( placeHolder: BibLibColor.PlaceHolder = BibLibColor.PlaceHolder(
color = BibLibColorPalette.LightGrey, color = BibLibColorPalette.LightGrey,

View file

@ -54,10 +54,12 @@ fun Book.toDetailUio(
) = BookDetailUio( ) = BookDetailUio(
id = id, id = id,
title = title, title = title,
authorId = author.firstOrNull()?.id,
author = author.joinToString { it.name }, author = author.joinToString { it.name },
rating = rating?.toFloat() ?: 0.0f, rating = rating?.toFloat() ?: 0.0f,
language = language?.displayLanguage?.capitalize() ?: "", language = language?.displayLanguage?.capitalize() ?: "",
date = releaseDate.shortDate(), date = releaseDate.shortDate(),
seriesId = series?.id,
series = toLabel(series), series = toLabel(series),
description = synopsis ?: "", description = synopsis ?: "",
cover = "${coverBaseUrl}/$id.jpg", cover = "${coverBaseUrl}/$id.jpg",