From 100f8d32bd4bc07e8b31f7801df16f966697c4b5 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Fri, 31 Mar 2023 12:54:22 +0200 Subject: [PATCH] Filter by author / series from the detail feature. --- .../composable/scaffold/DetailBottomSheet.kt | 8 ++++- .../ui/screen/home/BookSearchViewModel.kt | 30 +++++++++++++++++++ .../biblib/ui/screen/home/HomeScreen.kt | 20 +++++++++++-- .../ui/screen/home/detail/DetailScreen.kt | 7 ++++- .../screen/home/detail/DetailScreenContent.kt | 27 ++++++++++++----- .../home/detail/DetailScreenSendOption.kt | 2 +- .../biblib/ui/theme/color/BibLibColor.kt | 6 ++-- .../biblib/utils/extention/BookEx.kt | 2 ++ 8 files changed, 85 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/scaffold/DetailBottomSheet.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/scaffold/DetailBottomSheet.kt index c138fb6..b017622 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/composable/scaffold/DetailBottomSheet.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/composable/scaffold/DetailBottomSheet.kt @@ -20,6 +20,8 @@ val LocalDetailBottomSheetState = staticCompositionLocalOf 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, ) diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/BookSearchViewModel.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/BookSearchViewModel.kt index f978ab6..fa3007f 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/BookSearchViewModel.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/BookSearchViewModel.kt @@ -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() diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt index a344084..9386dcd 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/HomeScreen.kt @@ -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), ) }, diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreen.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreen.kt index b049ead..5420a2b 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreen.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreen.kt @@ -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, diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenContent.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenContent.kt index cb58bdc..2268ba5 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenContent.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenContent.kt @@ -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 = { }, ) } } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenSendOption.kt b/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenSendOption.kt index f4ec30b..b7f3269 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenSendOption.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/screen/home/detail/DetailScreenSendOption.kt @@ -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), diff --git a/app/src/main/java/com/pixelized/biblib/ui/theme/color/BibLibColor.kt b/app/src/main/java/com/pixelized/biblib/ui/theme/color/BibLibColor.kt index cf54274..e24eead 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/theme/color/BibLibColor.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/theme/color/BibLibColor.kt @@ -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, diff --git a/app/src/main/java/com/pixelized/biblib/utils/extention/BookEx.kt b/app/src/main/java/com/pixelized/biblib/utils/extention/BookEx.kt index ca9b493..b2050c1 100644 --- a/app/src/main/java/com/pixelized/biblib/utils/extention/BookEx.kt +++ b/app/src/main/java/com/pixelized/biblib/utils/extention/BookEx.kt @@ -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",