Catergorie Search basic impl
This commit is contained in:
parent
42b4e414a0
commit
c7603ca71e
12 changed files with 230 additions and 26 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package com.pixelized.biblib.database.dao
|
package com.pixelized.biblib.database.dao
|
||||||
|
|
||||||
|
import androidx.paging.DataSource
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
|
|
@ -8,6 +9,9 @@ import com.pixelized.biblib.database.data.AuthorDbo
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface AuthorDao {
|
interface AuthorDao {
|
||||||
|
@Query("SELECT * FROM ${AuthorDbo.TABLE}")
|
||||||
|
fun getAll(): DataSource.Factory<Int, AuthorDbo>
|
||||||
|
|
||||||
@Query("SELECT * FROM ${AuthorDbo.TABLE} WHERE ${AuthorDbo.ID} LIKE :id")
|
@Query("SELECT * FROM ${AuthorDbo.TABLE} WHERE ${AuthorDbo.ID} LIKE :id")
|
||||||
fun get(id: String?): AuthorDbo?
|
fun get(id: String?): AuthorDbo?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
package com.pixelized.biblib.database.dao
|
package com.pixelized.biblib.database.dao
|
||||||
|
|
||||||
|
import androidx.paging.DataSource
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import com.pixelized.biblib.database.data.AuthorDbo
|
||||||
import com.pixelized.biblib.database.data.GenreDbo
|
import com.pixelized.biblib.database.data.GenreDbo
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface GenreDao {
|
interface GenreDao {
|
||||||
|
@Query("SELECT * FROM ${GenreDbo.TABLE}")
|
||||||
|
fun getAll(): DataSource.Factory<Int, GenreDbo>
|
||||||
|
|
||||||
@Query("SELECT * FROM ${GenreDbo.TABLE} WHERE ${GenreDbo.ID} LIKE :id")
|
@Query("SELECT * FROM ${GenreDbo.TABLE} WHERE ${GenreDbo.ID} LIKE :id")
|
||||||
fun get(id: String?): GenreDbo?
|
fun get(id: String?): GenreDbo?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
package com.pixelized.biblib.database.dao
|
package com.pixelized.biblib.database.dao
|
||||||
|
|
||||||
|
import androidx.paging.DataSource
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import com.pixelized.biblib.database.data.GenreDbo
|
||||||
import com.pixelized.biblib.database.data.LanguageDbo
|
import com.pixelized.biblib.database.data.LanguageDbo
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface LanguageDao {
|
interface LanguageDao {
|
||||||
|
@Query("SELECT * FROM ${LanguageDbo.TABLE}")
|
||||||
|
fun getAll(): DataSource.Factory<Int, LanguageDbo>
|
||||||
|
|
||||||
@Query("SELECT * FROM ${LanguageDbo.TABLE} WHERE ${LanguageDbo.ID} LIKE :id")
|
@Query("SELECT * FROM ${LanguageDbo.TABLE} WHERE ${LanguageDbo.ID} LIKE :id")
|
||||||
fun get(id: String?): LanguageDbo?
|
fun get(id: String?): LanguageDbo?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
package com.pixelized.biblib.database.dao
|
package com.pixelized.biblib.database.dao
|
||||||
|
|
||||||
|
import androidx.paging.DataSource
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import com.pixelized.biblib.database.data.LanguageDbo
|
||||||
import com.pixelized.biblib.database.data.SeriesDbo
|
import com.pixelized.biblib.database.data.SeriesDbo
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface SeriesDao {
|
interface SeriesDao {
|
||||||
|
@Query("SELECT * FROM ${SeriesDbo.TABLE}")
|
||||||
|
fun getAll(): DataSource.Factory<Int, SeriesDbo>
|
||||||
|
|
||||||
@Query("SELECT * FROM ${SeriesDbo.TABLE} WHERE ${SeriesDbo.ID} LIKE :id")
|
@Query("SELECT * FROM ${SeriesDbo.TABLE} WHERE ${SeriesDbo.ID} LIKE :id")
|
||||||
fun get(id: String?): SeriesDbo?
|
fun get(id: String?): SeriesDbo?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,18 @@ class BookRepository @Inject constructor(
|
||||||
override fun getBooksSource(): DataSource.Factory<Int, Book> =
|
override fun getBooksSource(): DataSource.Factory<Int, Book> =
|
||||||
database.bookDao().getBook().map { it.toBook() }
|
database.bookDao().getBook().map { it.toBook() }
|
||||||
|
|
||||||
|
override fun getAuthorsSource(): DataSource.Factory<Int, Author> =
|
||||||
|
database.authorDao().getAll().map { it.toAuthor() }
|
||||||
|
|
||||||
|
override fun getSeriesSource(): DataSource.Factory<Int, Series> =
|
||||||
|
database.seriesDao().getAll().map { it.toSeries() }
|
||||||
|
|
||||||
|
override fun getGenresSource(): DataSource.Factory<Int, Genre> =
|
||||||
|
database.genreDao().getAll().map { it.toGenre() }
|
||||||
|
|
||||||
|
override fun getLanguagesSource(): DataSource.Factory<Int, Language> =
|
||||||
|
database.languageDao().getAll().map { it.toLanguage() }
|
||||||
|
|
||||||
override suspend fun update(data: List<Book>) {
|
override suspend fun update(data: List<Book>) {
|
||||||
val authors = mutableSetOf<AuthorDbo>()
|
val authors = mutableSetOf<AuthorDbo>()
|
||||||
val genres = mutableSetOf<GenreDbo>()
|
val genres = mutableSetOf<GenreDbo>()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.pixelized.biblib.repository.book
|
package com.pixelized.biblib.repository.book
|
||||||
|
|
||||||
import androidx.paging.DataSource
|
import androidx.paging.DataSource
|
||||||
import com.pixelized.biblib.model.book.Book
|
import com.pixelized.biblib.model.book.*
|
||||||
|
|
||||||
interface IBookRepository {
|
interface IBookRepository {
|
||||||
|
|
||||||
|
|
@ -11,5 +11,13 @@ interface IBookRepository {
|
||||||
|
|
||||||
fun getBooksSource(): DataSource.Factory<Int, Book>
|
fun getBooksSource(): DataSource.Factory<Int, Book>
|
||||||
|
|
||||||
|
fun getAuthorsSource() : DataSource.Factory<Int, Author>
|
||||||
|
|
||||||
|
fun getSeriesSource() : DataSource.Factory<Int, Series>
|
||||||
|
|
||||||
|
fun getGenresSource() : DataSource.Factory<Int, Genre>
|
||||||
|
|
||||||
|
fun getLanguagesSource() : DataSource.Factory<Int, Language>
|
||||||
|
|
||||||
suspend fun update(data: List<Book>)
|
suspend fun update(data: List<Book>)
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +49,13 @@ fun BottomSearchScaffold(
|
||||||
focusRequester = state.focusRequester,
|
focusRequester = state.focusRequester,
|
||||||
filter = state.filter,
|
filter = state.filter,
|
||||||
onClose = {
|
onClose = {
|
||||||
|
when(state.filter) {
|
||||||
|
is SearchFilter.Author -> searchViewModel.authors.confirm("")
|
||||||
|
is SearchFilter.Series -> searchViewModel.series.confirm("")
|
||||||
|
is SearchFilter.Genre -> searchViewModel.genre.confirm("")
|
||||||
|
is SearchFilter.Language -> searchViewModel.language.confirm("")
|
||||||
|
null -> Unit
|
||||||
|
}
|
||||||
state.collapse()
|
state.collapse()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -125,6 +132,13 @@ sealed class SearchFilter(
|
||||||
value = value,
|
value = value,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class Series(
|
||||||
|
value: String? = null,
|
||||||
|
): SearchFilter(
|
||||||
|
label = R.string.search_filter_serie,
|
||||||
|
value = value,
|
||||||
|
)
|
||||||
|
|
||||||
class Genre(
|
class Genre(
|
||||||
value: String? = null,
|
value: String? = null,
|
||||||
) : SearchFilter(
|
) : SearchFilter(
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ package com.pixelized.biblib.ui.screen.home.page.search
|
||||||
|
|
||||||
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.layout.Column
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.layout.imePadding
|
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
|
@ -18,10 +18,17 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
|
import androidx.paging.compose.items
|
||||||
import com.pixelized.biblib.ui.scaffold.LocalBottomSearchState
|
import com.pixelized.biblib.ui.scaffold.LocalBottomSearchState
|
||||||
import com.pixelized.biblib.ui.scaffold.SearchFilter
|
import com.pixelized.biblib.ui.scaffold.SearchFilter
|
||||||
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.default
|
import com.pixelized.biblib.utils.extention.default
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CategorySearchPage(
|
fun CategorySearchPage(
|
||||||
|
|
@ -31,26 +38,48 @@ fun CategorySearchPage(
|
||||||
onClose: () -> Unit = default(),
|
onClose: () -> Unit = default(),
|
||||||
) {
|
) {
|
||||||
val bottomSearchState = LocalBottomSearchState.current
|
val bottomSearchState = LocalBottomSearchState.current
|
||||||
|
|
||||||
CategorySearchPageContent(
|
CategorySearchPageContent(
|
||||||
focusRequester = focusRequester,
|
focusRequester = focusRequester,
|
||||||
filter = filter,
|
filter = filter,
|
||||||
onClose = onClose,
|
onClose = onClose,
|
||||||
searchValue = {
|
searchFlow = {
|
||||||
when (bottomSearchState.filter) {
|
when (bottomSearchState.filter) {
|
||||||
is SearchFilter.Author -> searchViewModel.author
|
is SearchFilter.Author -> searchViewModel.authors.filterFlow
|
||||||
is SearchFilter.Genre -> searchViewModel.genre
|
is SearchFilter.Series -> searchViewModel.series.filterFlow
|
||||||
is SearchFilter.Language -> searchViewModel.language
|
is SearchFilter.Genre -> searchViewModel.genre.filterFlow
|
||||||
null -> ""
|
is SearchFilter.Language -> searchViewModel.language.filterFlow
|
||||||
|
null -> emptyFlow()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataFlow = {
|
||||||
|
when (bottomSearchState.filter) {
|
||||||
|
is SearchFilter.Author -> searchViewModel.authors.dataFlow
|
||||||
|
is SearchFilter.Series -> searchViewModel.series.dataFlow
|
||||||
|
is SearchFilter.Genre -> searchViewModel.genre.dataFlow
|
||||||
|
is SearchFilter.Language -> searchViewModel.language.dataFlow
|
||||||
|
null -> emptyFlow()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSearchChange = {
|
onSearchChange = {
|
||||||
when (bottomSearchState.filter) {
|
when (bottomSearchState.filter) {
|
||||||
is SearchFilter.Author -> searchViewModel.filterAuthor(it)
|
is SearchFilter.Author -> searchViewModel.authors.filter(it)
|
||||||
is SearchFilter.Genre -> searchViewModel.filterGenre(it)
|
is SearchFilter.Series -> searchViewModel.series.filter(it)
|
||||||
is SearchFilter.Language -> searchViewModel.filterLanguage(it)
|
is SearchFilter.Genre -> searchViewModel.genre.filter(it)
|
||||||
|
is SearchFilter.Language -> searchViewModel.language.filter(it)
|
||||||
null -> Unit
|
null -> Unit
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onData = {
|
||||||
|
when (bottomSearchState.filter) {
|
||||||
|
is SearchFilter.Author -> searchViewModel.authors.confirm(it)
|
||||||
|
is SearchFilter.Series -> searchViewModel.series.confirm(it)
|
||||||
|
is SearchFilter.Genre -> searchViewModel.genre.confirm(it)
|
||||||
|
is SearchFilter.Language -> searchViewModel.language.confirm(it)
|
||||||
|
null -> Unit
|
||||||
|
}
|
||||||
|
bottomSearchState.collapse()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,10 +87,13 @@ fun CategorySearchPage(
|
||||||
fun CategorySearchPageContent(
|
fun CategorySearchPageContent(
|
||||||
focusRequester: FocusRequester = FocusRequester(),
|
focusRequester: FocusRequester = FocusRequester(),
|
||||||
filter: SearchFilter?,
|
filter: SearchFilter?,
|
||||||
searchValue: () -> String,
|
searchFlow: () -> Flow<String>,
|
||||||
|
dataFlow: () -> Flow<PagingData<String>> = { emptyFlow() },
|
||||||
onSearchChange: (String) -> Unit = default<String>(),
|
onSearchChange: (String) -> Unit = default<String>(),
|
||||||
|
onData: (String) -> Unit = default<String>(),
|
||||||
onClose: () -> Unit = default(),
|
onClose: () -> Unit = default(),
|
||||||
) {
|
) {
|
||||||
|
val data = dataFlow().collectAsLazyPagingItems()
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.imePadding()
|
.imePadding()
|
||||||
|
|
@ -98,7 +130,7 @@ fun CategorySearchPageContent(
|
||||||
text = "Rechercher"
|
text = "Rechercher"
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
value = searchValue(),
|
value = searchFlow().collectAsState(initial = "").value,
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
colors = TextFieldDefaults.outlinedTextFieldColors(
|
colors = TextFieldDefaults.outlinedTextFieldColors(
|
||||||
focusedBorderColor = Color.Transparent,
|
focusedBorderColor = Color.Transparent,
|
||||||
|
|
@ -107,6 +139,21 @@ fun CategorySearchPageContent(
|
||||||
),
|
),
|
||||||
onValueChange = onSearchChange
|
onValueChange = onSearchChange
|
||||||
)
|
)
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
items(items = data, key = { it }) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable { onData(it ?: "") }
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = MaterialTheme.bibLib.dimen.dp16),
|
||||||
|
style = MaterialTheme.typography.body1,
|
||||||
|
color = MaterialTheme.colors.onSurface,
|
||||||
|
text = it ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +164,7 @@ private fun CategorySearchPageContentPreview() {
|
||||||
BibLibTheme {
|
BibLibTheme {
|
||||||
CategorySearchPageContent(
|
CategorySearchPageContent(
|
||||||
filter = SearchFilter.Author(),
|
filter = SearchFilter.Author(),
|
||||||
searchValue = { "Asimov" },
|
searchFlow = { flow { "Asimov" } },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,21 +26,12 @@ 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.default
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SearchPage(
|
fun SearchPage(
|
||||||
searchViewModel: SearchViewModel = LocalSearchViewModel.current
|
searchViewModel: SearchViewModel = LocalSearchViewModel.current
|
||||||
) {
|
) {
|
||||||
val bottomSearchState = LocalBottomSearchState.current
|
val bottomSearchState = LocalBottomSearchState.current
|
||||||
val filters by remember {
|
val filters = rememberSearchFilter()
|
||||||
derivedStateOf {
|
|
||||||
listOf(
|
|
||||||
SearchFilter.Author(value = searchViewModel.author),
|
|
||||||
SearchFilter.Genre(value = searchViewModel.genre),
|
|
||||||
SearchFilter.Language(value = searchViewModel.language),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchPageContent(
|
SearchPageContent(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
|
@ -129,6 +120,29 @@ private fun SearchChipFilter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun rememberSearchFilter(
|
||||||
|
searchViewModel: SearchViewModel = LocalSearchViewModel.current
|
||||||
|
): List<SearchFilter> {
|
||||||
|
val authors by searchViewModel.authors.search
|
||||||
|
val genre by searchViewModel.genre.search
|
||||||
|
val language by searchViewModel.language.search
|
||||||
|
val series by searchViewModel.series.search
|
||||||
|
|
||||||
|
val filters by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
listOf(
|
||||||
|
SearchFilter.Author(value = authors),
|
||||||
|
SearchFilter.Genre(value = genre),
|
||||||
|
SearchFilter.Language(value = language),
|
||||||
|
SearchFilter.Series(value = series)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO)
|
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO)
|
||||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES)
|
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.pixelized.biblib.ui.screen.home.page.search
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import androidx.paging.*
|
||||||
|
import com.pixelized.biblib.repository.book.IBookRepository
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class SearchViewModel @Inject constructor(
|
||||||
|
bookRepository: IBookRepository,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
var search: String by mutableStateOf("")
|
||||||
|
private set
|
||||||
|
|
||||||
|
val authors = FilterManager(
|
||||||
|
scope = viewModelScope,
|
||||||
|
source = bookRepository.getAuthorsSource()
|
||||||
|
.map { it.name }
|
||||||
|
.asPagingSourceFactory(Dispatchers.IO)
|
||||||
|
)
|
||||||
|
|
||||||
|
val series = FilterManager(
|
||||||
|
scope = viewModelScope,
|
||||||
|
source = bookRepository.getSeriesSource()
|
||||||
|
.map { it.name }
|
||||||
|
.asPagingSourceFactory(Dispatchers.IO)
|
||||||
|
)
|
||||||
|
|
||||||
|
val genre = FilterManager(
|
||||||
|
scope = viewModelScope,
|
||||||
|
source = bookRepository.getGenresSource()
|
||||||
|
.map { it.name }
|
||||||
|
.asPagingSourceFactory(Dispatchers.IO)
|
||||||
|
)
|
||||||
|
|
||||||
|
val language = FilterManager(
|
||||||
|
scope = viewModelScope,
|
||||||
|
source = bookRepository.getLanguagesSource()
|
||||||
|
.map { it.displayLanguage }
|
||||||
|
.asPagingSourceFactory(Dispatchers.IO)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun search(criteria: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilterManager(
|
||||||
|
private val scope: CoroutineScope,
|
||||||
|
source: () -> PagingSource<Int, String>,
|
||||||
|
) {
|
||||||
|
private val _searchFlow = MutableStateFlow("")
|
||||||
|
val searchFlow: Flow<String> get() = _searchFlow
|
||||||
|
|
||||||
|
private val _filterFlow = MutableStateFlow("")
|
||||||
|
val filterFlow: Flow<String> get() = _filterFlow
|
||||||
|
|
||||||
|
val dataFlow: Flow<PagingData<String>> = Pager(
|
||||||
|
config = PagingConfig(pageSize = 30),
|
||||||
|
pagingSourceFactory = source,
|
||||||
|
).flow.cachedIn(scope).combine(this._filterFlow) { paging, filter ->
|
||||||
|
paging.filter { it.contains(filter, ignoreCase = true) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val filter: State<String>
|
||||||
|
@Composable get() = _filterFlow.collectAsState(initial = "")
|
||||||
|
|
||||||
|
val search: State<String>
|
||||||
|
@Composable get() = _searchFlow.collectAsState(initial = "")
|
||||||
|
|
||||||
|
fun filter(criteria: String) {
|
||||||
|
scope.launch { _filterFlow.emit(criteria) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun confirm(criteria: String) {
|
||||||
|
scope.launch { _searchFlow.emit(criteria) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
<string name="detail_emails_title">Envoyer cet eBook à :</string>
|
<string name="detail_emails_title">Envoyer cet eBook à :</string>
|
||||||
|
|
||||||
<string name="search_filter_author">Auteur</string>
|
<string name="search_filter_author">Auteur</string>
|
||||||
|
<string name="search_filter_serie">Série</string>
|
||||||
<string name="search_filter_genre">Genre</string>
|
<string name="search_filter_genre">Genre</string>
|
||||||
<string name="search_filter_language">Langue</string>
|
<string name="search_filter_language">Langue</string>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
<string name="detail_emails_title">Send this eBook to:</string>
|
<string name="detail_emails_title">Send this eBook to:</string>
|
||||||
|
|
||||||
<string name="search_filter_author">Author</string>
|
<string name="search_filter_author">Author</string>
|
||||||
|
<string name="search_filter_serie">Serie</string>
|
||||||
<string name="search_filter_genre">Genre</string>
|
<string name="search_filter_genre">Genre</string>
|
||||||
<string name="search_filter_language">Language</string>
|
<string name="search_filter_language">Language</string>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue