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

View file

@ -110,6 +110,36 @@ class BookSearchViewModel @Inject constructor(
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?) {
_search.value = criteria
searchSource?.invalidate()

View file

@ -103,9 +103,23 @@ fun HomeScreen(
) {
DetailBottomSheet(
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(
modifier = Modifier.systemBarsPadding(),
modifier = Modifier
.fillMaxSize()
.statusBarsPadding(),
avatar = profileViewModel.avatar,
search = bookViewModel.search,
onSearch = {
@ -514,9 +528,9 @@ private fun HomeToolbar(
TextField(
modifier = Modifier.weight(1f),
placeholder = {
label = {
Text(
color = MaterialTheme.colors.onSurface,
color = MaterialTheme.bibLib.colors.typography.medium,
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.UserUio
import com.pixelized.biblib.ui.theme.color.ShadowPalette
import com.pixelized.biblib.utils.extention.bibLib
import kotlinx.coroutines.launch
@Stable
@ -52,6 +51,8 @@ sealed class BookDetailUioErrorUio(
fun DetailScreen(
detailViewModel: BookDetailViewModel = hiltViewModel(),
profileViewModel: ProfileViewModel = hiltViewModel(),
onAuthor: (String?, Int?) -> Unit,
onSeries: (String?, Int?) -> Unit,
bookId: Int? = null,
) {
val detailState = LocalDetailBottomSheetState.current
@ -96,6 +97,10 @@ fun DetailScreen(
.padding(all = 16.dp)
.systemBarsPadding(),
book = detail,
onAuthor = { onAuthor(detail.author, detail.authorId) },
onSeries = { onSeries(detail.series, detail.seriesId) },
onMobi = { },
onEpub = { },
onSend = {
send(
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_YES
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@ -26,16 +27,12 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.text.HtmlCompat
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.ui.composable.SpannedText
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
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.placeholder
import com.skydoves.landscapist.CircularReveal
import com.skydoves.landscapist.glide.GlideImage
@ -47,10 +44,12 @@ import java.io.Serializable
data class BookDetailUio(
val id: Int,
val title: String,
val authorId: Int?,
val author: String,
val rating: Float,
val language: String,
val date: String?,
val seriesId: Int?,
val series: String?,
val description: String,
val cover: String,
@ -60,8 +59,10 @@ data class BookDetailUio(
fun preview() = BookDetailUio(
id = 90,
title = "Foundation",
authorId = null,
author = "Asimov",
date = "1951",
seriesId = null,
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...",
rating = 4.5f,
@ -76,9 +77,11 @@ data class BookDetailUio(
fun DetailScreenContent(
modifier: Modifier = Modifier,
book: BookDetailUio,
onMobi: () -> Unit = default(),
onEpub: () -> Unit = default(),
onSend: suspend () -> Unit = { },
onAuthor: () -> Unit,
onSeries: () -> Unit,
onMobi: () -> Unit,
onEpub: () -> Unit,
onSend: suspend () -> Unit,
) {
val scope = rememberCoroutineScope()
@ -162,6 +165,7 @@ fun DetailScreenContent(
.padding(bottom = 16.dp),
) {
Text(
modifier = Modifier.clickable(onClick = onAuthor),
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.h6,
color = MaterialTheme.colors.onSurface,
@ -201,7 +205,9 @@ fun DetailScreenContent(
modifier = Modifier.padding(bottom = 16.dp),
) {
TitleLabel(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onSeries),
title = stringResource(id = R.string.detail_series),
label = book.series ?: "-",
)
@ -262,6 +268,11 @@ private fun DetailScreenContentPreview() {
.verticalScroll(state = rememberScrollState())
.padding(all = 16.dp),
book = BookDetailUio.preview(),
onAuthor = { },
onSeries = { },
onMobi = { },
onEpub = { },
onSend = { },
)
}
}

View file

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

View file

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

View file

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