From 4e1d6635b8d76ba9424db3151dae6a58da8393bb Mon Sep 17 00:00:00 2001 From: Tlaster Date: Tue, 10 Dec 2024 15:20:09 +0900 Subject: [PATCH] [WIP] add local history search --- .../data/database/cache/CacaheDatabase.kt | 2 +- .../database/cache/dao/PagingTimelineDao.kt | 10 +++ .../data/database/cache/model/DbStatus.kt | 1 + .../settings/LocalHistoryPresenter.kt | 83 +++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/settings/LocalHistoryPresenter.kt diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/CacaheDatabase.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/CacaheDatabase.kt index c9c3bf12..c120eff5 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/CacaheDatabase.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/CacaheDatabase.kt @@ -6,7 +6,7 @@ import androidx.room.RoomDatabase import androidx.room.RoomDatabaseConstructor import androidx.room.TypeConverters -const val CACHE_DATABASE_VERSION = 13 +const val CACHE_DATABASE_VERSION = 14 @Database( entities = [ diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/dao/PagingTimelineDao.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/dao/PagingTimelineDao.kt index ebf663b8..18e72eb3 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/dao/PagingTimelineDao.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/dao/PagingTimelineDao.kt @@ -6,6 +6,7 @@ import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import androidx.room.RewriteQueriesToDropUnusedColumns import androidx.room.Transaction import dev.dimension.flare.data.database.cache.model.DbPagingTimeline import dev.dimension.flare.data.database.cache.model.DbPagingTimelineWithStatus @@ -20,6 +21,15 @@ interface PagingTimelineDao { accountKey: MicroBlogKey, ): PagingSource + @Transaction + @RewriteQueriesToDropUnusedColumns + @Query( + "SELECT * FROM DbPagingTimeline " + + "INNER JOIN DbStatus on DbStatus.statusKey = DbPagingTimeline.statusKey " + + "WHERE DbStatus.text like :query ORDER BY sortId DESC", + ) + fun getHistoryPagingSource(query: String): PagingSource + @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertAll(timeline: List) diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/model/DbStatus.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/model/DbStatus.kt index 6ff902c2..f45a0fe6 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/model/DbStatus.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/model/DbStatus.kt @@ -18,6 +18,7 @@ data class DbStatus( val userKey: MicroBlogKey?, val platformType: PlatformType, val content: StatusContent, + val text: String, // For Searching @PrimaryKey val id: String = "${accountKey}_$statusKey", ) diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/settings/LocalHistoryPresenter.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/settings/LocalHistoryPresenter.kt new file mode 100644 index 00000000..254930bc --- /dev/null +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/ui/presenter/settings/LocalHistoryPresenter.kt @@ -0,0 +1,83 @@ +package dev.dimension.flare.ui.presenter.settings + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.compose.collectAsLazyPagingItems +import androidx.paging.map +import dev.dimension.flare.common.PagingState +import dev.dimension.flare.common.toPagingState +import dev.dimension.flare.data.database.cache.CacheDatabase +import dev.dimension.flare.data.datasource.microblog.StatusEvent +import dev.dimension.flare.data.repository.AccountRepository +import dev.dimension.flare.ui.model.UiState +import dev.dimension.flare.ui.model.UiTimeline +import dev.dimension.flare.ui.model.collectAsUiState +import dev.dimension.flare.ui.model.flatMap +import dev.dimension.flare.ui.model.map +import dev.dimension.flare.ui.model.mapper.render +import dev.dimension.flare.ui.presenter.PresenterBase +import kotlinx.coroutines.flow.map +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class LocalHistoryPresenter : + PresenterBase(), + KoinComponent { + private val database: CacheDatabase by inject() + private val accountRepository: AccountRepository by inject() + + interface State { + val data: PagingState + + fun setQuery(value: String) + } + + @Composable + override fun body(): State { + var query by remember { mutableStateOf("") } + val allAccounts by accountRepository.allAccounts.collectAsUiState() + val paging = + remember(query) { + if (query.isEmpty()) { + UiState.Error(Throwable("Query is empty")) + } else { + Pager( + config = PagingConfig(pageSize = 20), + ) { + database.pagingTimelineDao().getHistoryPagingSource(query = query) + }.flow.let { + UiState.Success(it) + } + } + } + val data = + remember(paging, allAccounts) { + allAccounts.flatMap { accounts -> + paging.map { pagingData -> + pagingData.map { + it.map { + val accountKey = it.timeline.accountKey + val event = accounts.first { it.accountKey == accountKey }.dataSource as StatusEvent + it.render(event) + } + } + } + } + }.map { + it.collectAsLazyPagingItems() + }.toPagingState() + + return object : State { + override fun setQuery(value: String) { + query = value + } + + override val data: PagingState = data + } + } +}