Implement full text search

This commit is contained in:
Kirill Kamakin
2022-11-13 09:52:52 +01:00
parent 21abf38282
commit 79631a7eb0
12 changed files with 285 additions and 12 deletions

View File

@@ -12,4 +12,6 @@ interface RecipeRepo {
suspend fun refreshRecipeInfo(recipeSlug: String): Result<Unit>
suspend fun loadRecipeInfo(recipeId: String): FullRecipeEntity?
fun setSearchName(name: String?)
}

View File

@@ -9,7 +9,7 @@ import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
interface RecipeStorage {
suspend fun saveRecipes(recipes: List<RecipeSummaryInfo>)
fun queryRecipes(): PagingSource<Int, RecipeSummaryEntity>
fun queryRecipes(query: String?): PagingSource<Int, RecipeSummaryEntity>
suspend fun refreshAll(recipes: List<RecipeSummaryInfo>)

View File

@@ -35,9 +35,11 @@ class RecipeStorageImpl @Inject constructor(
}
override fun queryRecipes(): PagingSource<Int, RecipeSummaryEntity> {
logger.v { "queryRecipes() called" }
return recipeDao.queryRecipesByPages()
override fun queryRecipes(query: String?): PagingSource<Int, RecipeSummaryEntity> {
logger.v { "queryRecipes() called with: query = $query" }
return if (query == null) recipeDao.queryRecipesByPages()
else recipeDao.queryRecipesByPages(query)
}
override suspend fun refreshAll(recipes: List<RecipeSummaryInfo>) {

View File

@@ -0,0 +1,8 @@
package gq.kirmanak.mealient.data.recipes.impl
import androidx.paging.PagingSource
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
interface RecipePagingSourceFactory : () -> PagingSource<Int, RecipeSummaryEntity> {
fun setQuery(newQuery: String?)
}

View File

@@ -0,0 +1,29 @@
package gq.kirmanak.mealient.data.recipes.impl
import androidx.paging.PagingSource
import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
import gq.kirmanak.mealient.logging.Logger
import java.util.concurrent.atomic.AtomicReference
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RecipePagingSourceFactoryImpl @Inject constructor(
private val recipeStorage: RecipeStorage,
private val logger: Logger,
) : RecipePagingSourceFactory {
private val query = AtomicReference<String>(null)
override fun invoke(): PagingSource<Int, RecipeSummaryEntity> {
val currentQuery = query.get()
logger.d { "Creating paging source, query is $currentQuery" }
return recipeStorage.queryRecipes(currentQuery)
}
override fun setQuery(newQuery: String?) {
logger.v { "setQuery() called with: newQuery = $newQuery" }
query.set(newQuery)
}
}

View File

@@ -19,10 +19,12 @@ import javax.inject.Singleton
class RecipeRepoImpl @Inject constructor(
private val mediator: RecipesRemoteMediator,
private val storage: RecipeStorage,
private val pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>,
private val pagingSourceFactory: RecipePagingSourceFactory,
private val invalidatingPagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>,
private val dataSource: RecipeDataSource,
private val logger: Logger,
) : RecipeRepo {
override fun createPager(): Pager<Int, RecipeSummaryEntity> {
logger.v { "createPager() called" }
val pagingConfig = PagingConfig(pageSize = 5, enablePlaceholders = true)
@@ -53,4 +55,10 @@ class RecipeRepoImpl @Inject constructor(
logger.v { "loadRecipeInfo() returned: $recipeInfo" }
return recipeInfo
}
override fun setSearchName(name: String?) {
logger.v { "setSearchName() called with: name = $name" }
pagingSourceFactory.setQuery(name)
invalidatingPagingSourceFactory.invalidate()
}
}

View File

@@ -13,9 +13,7 @@ import gq.kirmanak.mealient.data.network.MealieDataSourceWrapper
import gq.kirmanak.mealient.data.recipes.RecipeRepo
import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
import gq.kirmanak.mealient.data.recipes.db.RecipeStorageImpl
import gq.kirmanak.mealient.data.recipes.impl.RecipeImageUrlProvider
import gq.kirmanak.mealient.data.recipes.impl.RecipeImageUrlProviderImpl
import gq.kirmanak.mealient.data.recipes.impl.RecipeRepoImpl
import gq.kirmanak.mealient.data.recipes.impl.*
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
import gq.kirmanak.mealient.ui.recipes.images.RecipeModelLoaderFactory
@@ -46,13 +44,17 @@ interface RecipeModule {
@Singleton
fun bindModelLoaderFactory(recipeModelLoaderFactory: RecipeModelLoaderFactory): ModelLoaderFactory<RecipeSummaryEntity, InputStream>
@Binds
@Singleton
fun bindRecipePagingSourceFactory(recipePagingSourceFactoryImpl: RecipePagingSourceFactoryImpl): RecipePagingSourceFactory
companion object {
@Provides
@Singleton
fun provideRecipePagingSourceFactory(
recipeStorage: RecipeStorage
) = InvalidatingPagingSourceFactory { recipeStorage.queryRecipes() }
factory: RecipePagingSourceFactory,
) = InvalidatingPagingSourceFactory(factory)
@Provides
@Singleton

View File

@@ -6,6 +6,7 @@ import gq.kirmanak.mealient.R
import gq.kirmanak.mealient.data.auth.AuthRepo
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
import gq.kirmanak.mealient.data.recipes.RecipeRepo
import gq.kirmanak.mealient.logging.Logger
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -18,6 +19,7 @@ class MainActivityViewModel @Inject constructor(
private val logger: Logger,
private val disclaimerStorage: DisclaimerStorage,
private val serverInfoRepo: ServerInfoRepo,
private val recipeRepo: RecipeRepo,
) : ViewModel() {
private val _uiState = MutableLiveData(MainActivityUiState())
@@ -55,5 +57,6 @@ class MainActivityViewModel @Inject constructor(
fun onSearchQuery(query: String) {
logger.v { "onSearchQuery() called with: query = $query" }
recipeRepo.setSearchName(query)
}
}