-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
234 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
feature/match/src/commonMain/kotlin/com/stslex/feature/match/navigation/MatchRouter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
package com.stslex.feature.match.navigation | ||
|
||
import com.stslex.core.ui.mvi.Router | ||
import com.stslex.feature.match.ui.store.MatchStoreComponent.Navigation | ||
import com.stslex.feature.match.ui.store.MatchStore.Navigation | ||
|
||
interface MatchRouter : Router<Navigation> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
181 changes: 56 additions & 125 deletions
181
feature/match/src/commonMain/kotlin/com/stslex/feature/match/ui/store/MatchStore.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,142 +1,73 @@ | ||
package com.stslex.feature.match.ui.store | ||
|
||
import com.stslex.core.core.AppDispatcher | ||
import com.stslex.core.database.store.UserStore | ||
import com.stslex.core.ui.base.mapToAppError | ||
import com.stslex.core.ui.mvi.BaseStore | ||
import androidx.compose.runtime.Stable | ||
import com.stslex.core.ui.base.paging.PagingState | ||
import com.stslex.core.ui.mvi.Store | ||
import com.stslex.core.ui.mvi.Store.Event.Snackbar | ||
import com.stslex.core.ui.pager.StorePager | ||
import com.stslex.core.ui.pager.StorePagerImpl | ||
import com.stslex.feature.match.domain.interactor.MatchInteractor | ||
import com.stslex.feature.match.navigation.MatchRouter | ||
import com.stslex.core.ui.navigation.args.MatchScreenArgs | ||
import com.stslex.feature.match.ui.model.MatchUiModel | ||
import com.stslex.feature.match.ui.model.toUi | ||
import com.stslex.feature.match.ui.store.MatchStoreComponent.Action | ||
import com.stslex.feature.match.ui.store.MatchStoreComponent.Event | ||
import com.stslex.feature.match.ui.store.MatchStoreComponent.Navigation | ||
import com.stslex.feature.match.ui.store.MatchStoreComponent.State | ||
|
||
// todo refactor pager state for UI https://github.com/stslex/Wizard/issues/35 | ||
// todo add base store pager binding https://github.com/stslex/Wizard/issues/36 | ||
// todo add query support for pager https://github.com/stslex/Wizard/issues/37 | ||
|
||
class MatchStore( | ||
appDispatcher: AppDispatcher, | ||
router: MatchRouter, | ||
private val interactor: MatchInteractor, | ||
private val userStore: UserStore | ||
) : BaseStore<State, Event, Action, Navigation>( | ||
appDispatcher = appDispatcher, | ||
router = router, | ||
initialState = State.INITIAL | ||
) { | ||
|
||
private val pager: StorePager<MatchUiModel> = StorePagerImpl( | ||
request = { page, pageSize -> | ||
interactor.getMatches( | ||
uuid = state.value.uuid, | ||
page = page, | ||
pageSize = pageSize | ||
) | ||
}, | ||
scope = scope, | ||
mapper = { it.toUi() } | ||
) | ||
|
||
override fun process(action: Action) { | ||
when (action) { | ||
is Action.Init -> actionInit(action) | ||
is Action.LoadMore -> actionLoadMore() | ||
is Action.OnMatchClick -> actionOnMatchClick(action) | ||
is Action.OnRetryClick -> actionRetryClick() | ||
is Action.Refresh -> actionRefresh() | ||
is Action.Logout -> actionLogout() | ||
is Action.RepeatLastAction -> actionRepeatLastAction() | ||
} | ||
} | ||
import com.stslex.feature.match.ui.store.MatchStore.Action | ||
import com.stslex.feature.match.ui.store.MatchStore.Event | ||
import com.stslex.feature.match.ui.store.MatchStore.State | ||
|
||
private fun actionInit(action: Action.Init) { | ||
pager.state.launch { pagerState -> | ||
updateState { currentState -> | ||
currentState.copy( | ||
pagingState = pagerState | ||
) | ||
} | ||
} | ||
pager.loadState.launch { loadState -> | ||
updateState { currentState -> | ||
currentState.copy( | ||
screen = loadState.toUi() | ||
) | ||
} | ||
} | ||
pager.loadEvents.launch { | ||
sendEvent( | ||
Event.ShowSnackbar(Snackbar.Error("error load matches")) | ||
) | ||
} | ||
pager.initialLoad() | ||
updateState { currentState -> | ||
currentState.copy( | ||
isSelf = action.args.isSelf, | ||
uuid = action.args.uuid ?: userStore.uuid, | ||
// todo make more representative logic with store components implementation https://github.com/stslex/Wizard/issues/34 | ||
interface MatchStore : Store<State, Event, Action> { | ||
|
||
@Stable | ||
data class State( | ||
val screen: MatchScreenState, | ||
val uuid: String, | ||
val isSelf: Boolean, | ||
val pagingState: PagingState<MatchUiModel> | ||
) : Store.State { | ||
|
||
companion object { | ||
|
||
val INITIAL = State( | ||
screen = MatchScreenState.Shimmer, | ||
pagingState = PagingState.default(), | ||
uuid = "", | ||
isSelf = false | ||
) | ||
} | ||
pager.initialLoad() | ||
} | ||
|
||
private fun actionLoadMore() { | ||
pager.load() | ||
} | ||
@Stable | ||
sealed interface Event : Store.Event { | ||
|
||
private fun actionOnMatchClick(action: Action.OnMatchClick) { | ||
navigate(Navigation.MatchDetails(action.matchUuid)) | ||
data class ShowSnackbar( | ||
val snackbar: Snackbar | ||
) : Event | ||
} | ||
|
||
private fun actionRetryClick() { | ||
pager.retry() | ||
} | ||
@Stable | ||
sealed interface Action : Store.Action { | ||
|
||
private fun actionRefresh() { | ||
pager.refresh() | ||
} | ||
data class Init( | ||
val args: MatchScreenArgs | ||
) : Action | ||
|
||
data object Refresh : Action | ||
|
||
data object LoadMore : Action | ||
|
||
data class OnMatchClick( | ||
val matchUuid: String | ||
) : Action | ||
|
||
data object OnRetryClick : Action | ||
|
||
private fun actionLogout() { | ||
launch( | ||
action = { | ||
interactor.logout() | ||
}, | ||
onSuccess = { | ||
navigate(Navigation.LogOut) | ||
}, | ||
onError = { error -> | ||
val appError = error.mapToAppError("error logout") | ||
if (state.value.screen is MatchScreenState.Content) { | ||
sendEvent( | ||
Event.ShowSnackbar(Snackbar.Error(appError.message)) | ||
) | ||
} else { | ||
updateState { currentState -> | ||
currentState.copy( | ||
screen = MatchScreenState.Error(appError) | ||
) | ||
} | ||
} | ||
} | ||
) | ||
data object Logout : Action | ||
|
||
data object RepeatLastAction : Action, Store.Action.RepeatLastAction | ||
} | ||
|
||
private fun actionRepeatLastAction() { | ||
val lastAction = lastAction ?: return | ||
updateState { currentState -> | ||
val screen = when (currentState.screen) { | ||
is MatchScreenState.Content -> MatchScreenState.Content.Refresh | ||
is MatchScreenState.Error, | ||
is MatchScreenState.Shimmer, | ||
is MatchScreenState.Empty -> MatchScreenState.Shimmer | ||
} | ||
currentState.copy(screen = screen) | ||
} | ||
process(lastAction) | ||
@Stable | ||
sealed interface Navigation : Store.Navigation { | ||
|
||
data class MatchDetails(val matchUuid: String) : Navigation | ||
|
||
data object LogOut : Navigation | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.