Skip to content

Commit

Permalink
feat: better towns filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
makeevrserg committed Mar 14, 2024
1 parent 3457c65 commit e013ff9
Show file tree
Hide file tree
Showing 38 changed files with 431 additions and 213 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.makeevrserg.empireprojekt.mobile.features.rating.users.data

import kotlinx.coroutines.flow.StateFlow
import ru.astrainteractive.empireapi.models.rating.RatingListRequest
import ru.astrainteractive.empireapi.models.rating.RatingUserModel
import ru.astrainteractive.empireapi.models.rating.RatingsFilterModel
import ru.astrainteractive.klibs.paging.context.IntPageContext
import ru.astrainteractive.klibs.paging.state.PagingState

internal interface RatingUsersRepository {
fun updateRequest(request: RatingListRequest)
fun updateRequest(request: RatingsFilterModel)
suspend fun loadNextPage()
suspend fun reset()
val state: StateFlow<PagingState<RatingUserModel, IntPageContext>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext
import ru.astrainteractive.empireapi.models.rating.RatingListRequest
import ru.astrainteractive.empireapi.models.rating.RatingUserModel
import ru.astrainteractive.empireapi.models.rating.RatingsFilterModel
import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers
import ru.astrainteractive.klibs.paging.IntPagerCollector
import ru.astrainteractive.klibs.paging.context.IntPageContext
Expand All @@ -17,7 +17,7 @@ internal class RatingUsersRepositoryImpl(
private val ratingApi: RatingApi,
private val dispatchers: KotlinDispatchers
) : RatingUsersRepository {
private val request = MutableStateFlow(RatingListRequest())
private val request = MutableStateFlow(RatingsFilterModel())

private val pagingCollector = IntPagerCollector(
initialPage = 0,
Expand Down Expand Up @@ -48,7 +48,7 @@ internal class RatingUsersRepositoryImpl(
pagingCollector.loadNextPage()
}

override fun updateRequest(request: RatingListRequest) {
override fun updateRequest(request: RatingsFilterModel) {
this.request.update {
request
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.makeevrserg.empireprojekt.mobile.features.rating.users.presentation

import kotlinx.coroutines.flow.StateFlow
import ru.astrainteractive.empireapi.models.rating.RatingListRequest
import ru.astrainteractive.empireapi.models.rating.RatingUserModel
import ru.astrainteractive.empireapi.models.rating.RatingsFilterModel

interface RatingUsersComponent {
val model: StateFlow<Model>
Expand All @@ -15,7 +15,7 @@ interface RatingUsersComponent {

data class Model(
val items: List<RatingUserModel> = emptyList(),
val request: RatingListRequest = RatingListRequest(),
val request: RatingsFilterModel = RatingsFilterModel(),
val isLoading: Boolean = false,
val isFailure: Boolean = false,
val isLastPage: Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import com.arkivanov.mvikotlin.core.store.Store
import com.makeevrserg.empireprojekt.mobile.features.rating.users.store.RatingUsersStore.Intent
import com.makeevrserg.empireprojekt.mobile.features.rating.users.store.RatingUsersStore.Label
import com.makeevrserg.empireprojekt.mobile.features.rating.users.store.RatingUsersStore.State
import ru.astrainteractive.empireapi.models.rating.RatingListRequest
import ru.astrainteractive.empireapi.models.rating.RatingUserModel
import ru.astrainteractive.empireapi.models.rating.RatingsFilterModel
import ru.astrainteractive.klibs.paging.context.IntPageContext
import ru.astrainteractive.klibs.paging.state.PagingState

internal interface RatingUsersStore : Store<Intent, State, Label> {
data class State(
val items: List<RatingUserModel> = emptyList(),
val request: RatingListRequest = RatingListRequest(),
val request: RatingsFilterModel = RatingsFilterModel(),
val isLoading: Boolean = false,
val isFailure: Boolean = false,
val isLastPage: Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.makeevrserg.empireprojekt.mobile.features.towny.towns.data

import com.makeevrserg.empireprojekt.mobile.features.towny.towns.data.paging.TownyPagingCollector
import ru.astrainteractive.empireapi.models.towny.TownModel
import ru.astrainteractive.empireapi.models.towny.TownsFilter
import ru.astrainteractive.empireapi.models.towny.TownsFilterModel

internal interface TownsRepository {
val pagingCollector: TownyPagingCollector<TownModel>
suspend fun updateFilter(buildFilter: (TownsFilter) -> TownsFilter)
suspend fun updateFilter(buildFilter: (TownsFilterModel) -> TownsFilterModel)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import com.makeevrserg.empireprojekt.mobile.api.empireapi.TownyApi
import com.makeevrserg.empireprojekt.mobile.features.towny.towns.data.paging.TownyPagingCollector
import com.makeevrserg.empireprojekt.mobile.features.towny.towns.storage.TownsFilterStorageValue
import com.russhwolf.settings.Settings
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.job
import kotlinx.coroutines.withContext
import ru.astrainteractive.empireapi.models.towny.TownModel
import ru.astrainteractive.empireapi.models.towny.TownsFilter
import ru.astrainteractive.empireapi.models.towny.TownsFilterModel
import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers
import ru.astrainteractive.klibs.paging.PagingCollectorExt.submitList
import ru.astrainteractive.klibs.paging.PagingCollectorExt.updatePageContext
import ru.astrainteractive.klibs.paging.data.LambdaPagedListDataSource

internal class TownsRepositoryImpl(
Expand All @@ -20,9 +24,12 @@ internal class TownsRepositoryImpl(
settings = settings,
key = "towns_filter_storage_key"
)
private var currentJob: Job? = null

private suspend fun loadPage(page: Int, filter: TownsFilter): Result<List<TownModel>> {
return runCatching {
private suspend fun loadPage(page: Int, filter: TownsFilterModel): Result<List<TownModel>> = coroutineScope {
currentJob?.cancelAndJoin()
currentJob = this.coroutineContext.job
runCatching {
withContext(dispatchers.IO) {
townyApi.towns(
page = page,
Expand All @@ -41,24 +48,12 @@ internal class TownsRepositoryImpl(
initialFilter = townsFilterStorageValue.value
)

override suspend fun updateFilter(buildFilter: (TownsFilter) -> TownsFilter) {
pagingCollector.submitList(emptyList())

pagingCollector.update { state ->
val newFilter = buildFilter.invoke(state.pageContext.filter)
townsFilterStorageValue.save(newFilter)

state.copy(
pageContext = state.pageContext.copy(
page = 0,
filter = newFilter
),
items = emptyList(),
isLoading = false,
isFailure = false,
isLastPage = false
)
}
override suspend fun updateFilter(buildFilter: (TownsFilterModel) -> TownsFilterModel) {
val newFilter = buildFilter.invoke(pagingCollector.state.value.pageContext.filter)
townsFilterStorageValue.save(newFilter)
currentJob?.cancelAndJoin()
pagingCollector.reset()
pagingCollector.updatePageContext { it.copy(filter = newFilter) }
pagingCollector.loadNextPage()
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.makeevrserg.empireprojekt.mobile.features.towny.towns.data.paging

import ru.astrainteractive.empireapi.models.towny.TownsFilter
import ru.astrainteractive.empireapi.models.towny.TownsFilterModel
import ru.astrainteractive.klibs.paging.context.PageContext

internal data class TownyPageContext(
val page: Int = 0,
val filter: TownsFilter
val filter: TownsFilterModel
) : PageContext {
object Factory : PageContext.Factory<TownyPageContext> {
override fun next(pageContext: TownyPageContext): TownyPageContext {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.makeevrserg.empireprojekt.mobile.features.towny.towns.data.paging

import ru.astrainteractive.empireapi.models.towny.TownsFilter
import ru.astrainteractive.empireapi.models.towny.TownsFilterModel
import ru.astrainteractive.klibs.paging.DefaultPagingCollector
import ru.astrainteractive.klibs.paging.PagingCollector
import ru.astrainteractive.klibs.paging.data.PagedListDataSource
Expand All @@ -10,7 +10,7 @@ internal class TownyPagingCollector<T>(
private val initialPage: Int = 0,
private val pageSize: Int = 10,
private val pager: PagedListDataSource<T, TownyPageContext>,
private val initialFilter: TownsFilter
private val initialFilter: TownsFilterModel
) : PagingCollector<T, TownyPageContext> by DefaultPagingCollector(
initialPagingState = PagingState(
pageContext = TownyPageContext(page = initialPage, filter = initialFilter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import com.arkivanov.decompose.ComponentContext
import com.arkivanov.essenty.instancekeeper.getOrCreate
import com.makeevrserg.empireprojekt.mobile.features.towny.towns.di.TownsDependencies
import kotlinx.coroutines.flow.StateFlow
import ru.astrainteractive.empireapi.models.towny.LocalSortOrder
import ru.astrainteractive.empireapi.models.towny.TownPublicType
import ru.astrainteractive.empireapi.models.towny.TownSortBy
import ru.astrainteractive.klibs.mikro.core.util.next

@Suppress("TooManyFunctions")
internal class DefaultTownsComponent(
componentContext: ComponentContext,
dependencies: TownsDependencies
Expand All @@ -26,14 +28,41 @@ internal class DefaultTownsComponent(
}

override fun updateQuery(query: String) {
townsFeature.updateQuery(query)
townsFeature.updateFilter { it.copy(query = query) }
}

override fun selectPublicType(townPublicType: TownPublicType) {
townsFeature.selectPublicType(townPublicType)
private fun LocalSortOrder?.next(): LocalSortOrder {
return this?.next(LocalSortOrder.entries.toTypedArray()) ?: LocalSortOrder.entries.first()
}
private fun TownPublicType?.next(): TownPublicType {
return this?.next(TownPublicType.entries.toTypedArray()) ?: TownPublicType.entries.first()
}

override fun nextPublicType() {
townsFeature.updateFilter { it.copy(publicType = it.publicType.next()) }
}

override fun nextNameSort() {
townsFeature.updateFilter { it.copy(nameSort = it.nameSort.next()) }
}

override fun nextTagSort() {
townsFeature.updateFilter { it.copy(tagSort = it.tagSort.next()) }
}

override fun nextFounderSort() {
townsFeature.updateFilter { it.copy(founderSort = it.founderSort.next()) }
}

override fun nextNationSort() {
townsFeature.updateFilter { it.copy(nationSort = it.nationSort.next()) }
}

override fun nextDateSort() {
townsFeature.updateFilter { it.copy(dateSort = it.dateSort.next()) }
}

override fun selectSortType(townSortBy: TownSortBy) {
townsFeature.selectSortType(townSortBy)
override fun nextResidentsSort() {
townsFeature.updateFilter { it.copy(residentsSort = it.residentsSort.next()) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package com.makeevrserg.empireprojekt.mobile.features.towny.towns.presentation

import kotlinx.coroutines.flow.StateFlow
import ru.astrainteractive.empireapi.models.towny.TownModel
import ru.astrainteractive.empireapi.models.towny.TownPublicType
import ru.astrainteractive.empireapi.models.towny.TownSortBy
import ru.astrainteractive.empireapi.models.towny.TownsFilter
import ru.astrainteractive.empireapi.models.towny.TownsFilterModel

interface TownsComponent {
val model: StateFlow<Model>
Expand All @@ -15,13 +13,23 @@ interface TownsComponent {

fun updateQuery(query: String)

fun selectPublicType(townPublicType: TownPublicType)
fun nextPublicType()

fun selectSortType(townSortBy: TownSortBy)
fun nextNameSort()

fun nextTagSort()

fun nextFounderSort()

fun nextNationSort()

fun nextDateSort()

fun nextResidentsSort()

data class Model(
val items: List<TownModel> = emptyList(),
val filter: TownsFilter,
val filter: TownsFilterModel,
val isLoading: Boolean = false,
val isFailure: Boolean = false,
val isLastPage: Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package com.makeevrserg.empireprojekt.mobile.features.towny.towns.presentation

import com.makeevrserg.empireprojekt.mobile.features.towny.towns.di.TownsDependencies
import kotlinx.coroutines.launch
import ru.astrainteractive.empireapi.models.towny.TownPublicType
import ru.astrainteractive.empireapi.models.towny.TownSortBy
import ru.astrainteractive.empireapi.models.towny.TownsFilterModel
import ru.astrainteractive.klibs.mikro.core.util.mapStateFlow
import ru.astrainteractive.klibs.mikro.extensions.arkivanov.CoroutineFeature

Expand All @@ -20,22 +19,8 @@ internal class TownsFeature(
townsRepository.pagingCollector.reset()
}

fun updateQuery(query: String) = launch {
townsRepository.updateFilter { filter ->
filter.copy(query = query)
}
}

fun selectPublicType(townPublicType: TownPublicType) = launch {
townsRepository.updateFilter { filter ->
filter.copy(publicType = townPublicType)
}
}

fun selectSortType(townSortBy: TownSortBy) = launch {
townsRepository.updateFilter { filter ->
filter.copy(sortBy = townSortBy)
}
fun updateFilter(block: (TownsFilterModel) -> TownsFilterModel) = launch {
townsRepository.updateFilter(block)
}

val model = townsRepository.pagingCollector.state.mapStateFlow {
Expand Down
Loading

0 comments on commit e013ff9

Please sign in to comment.