Skip to content

Instantly share code, notes, and snippets.

View motorro's full-sized avatar

Nikolai Kotchetkov motorro

View GitHub Profile
@motorro
motorro / WelcomeUiState.kt
Created August 14, 2022 11:31
UI-state adapter
sealed class WelcomeUiState {
/**
* Login state wrapper
* @property value Login UI state
*/
data class Login(val value: LoginUiState) : WelcomeUiState()
/**
* Register state wrapper
* @property value Register UI state
@motorro
motorro / WelcomeGesture.kt
Created August 14, 2022 11:28
Gesture adapter
sealed class WelcomeGesture {
// Native gestures...
/**
* Login flow gesture
* @property value Login flow gesture
*/
data class Login(val value: LoginGesture) : WelcomeGesture()
/**
@motorro
motorro / ModuleSystem.md
Created August 14, 2022 11:21
Module system
Module name Gestures UI-states
welcome WelcomeGesture WelcomeUiState
login LoginGesture LoginUiState
commonregister RegisterGesture RegisterUiState
@motorro
motorro / LoginContext.kt
Created August 14, 2022 11:18
Feature module context
interface LoginContext {
/**
* Flow host
*/
val host: WelcomeFeatureHost
// Other dependencies...
}
@motorro
motorro / WelcomeFeatureHost.kt
Last active August 16, 2022 10:17
Parent module interface
interface WelcomeFeatureHost {
/**
* Returns user to email entry screen
*/
fun backToEmailEntry()
/**
* Authentication complete
*/
fun complete()
@motorro
motorro / WithIdleViewModel.kt
Created August 13, 2022 07:01
Lifecycle-aware view-model
class WithIdleViewModel : ViewModel() {
/**
* Creates initial state for state-machine
* You could process a deep-link here or restore from a saved state
*/
private fun initStateMachine(): CommonMachineState<SomeGesture, SomeUiState> = InitialState()
/**
* State-machine instance
*/
@motorro
motorro / LoginViewModel.kt
Created August 7, 2022 13:32
ViewModel with a state-factory
@HiltViewModel
class LoginViewModel @Inject constructor(private val factory: LoginStateFactory) : ViewModel() {
/**
* Creates initializing state
*/
private fun initializeStateMachine(): CommonMachineState<WelcomeGesture, WelcomeUiState> {
// Obtain data required to start from a saved-state handle or injection
val commonData = LoginDataState()
return factory.passwordEntry(commonData)
@motorro
motorro / CredentialsCheckingStateTest.kt
Created August 7, 2022 13:30
Mocking state dependencies
class CredentialsCheckStateTest {
private val data = LoginDataState()
private val factory: LoginStateFactory = mockk()
private val passwordEntry: LoginState = mockk()
@Test
fun returnsToPasswordEntryOnBack() = runTest {
every { factory.passwordEntry(any()) } returns passwordEntry
state.start(stateMachine)
class CredentialsCheckState(context: LoginContext) : LoginState(context) {
// State logic...
/**
* A part of [process] template to process UI gesture
*/
override fun doProcess(gesture: LoginGesture) = when(gesture) {
LoginGesture.Back -> onBack()
else -> super.doProcess(gesture)
@motorro
motorro / LoginStateFactoryImpl.kt
Created August 7, 2022 13:25
Login state factory implementation
@LoginScope
class LoginStateFactoryImpl @Inject constructor(
host: WelcomeFeatureHost, // External interface
renderer: LoginRenderer, // Renderer
private val createCredentialsCheck: CredentialsCheckState.Factory // Concrete state factory
) : LoginStateFactory {
// Dependencies common for each state provided through the context
private val context: LoginContext = object : LoginContext {
override val factory: LoginStateFactory = this@Impl