-
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.
✨ Add edit profile decompose component and navigation
Add edit profile component with MVI pattern, including store, model, and component classes. Update navigation to handle edit profile flow with proper state management.
- Loading branch information
Showing
9 changed files
with
193 additions
and
16 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
58 changes: 58 additions & 0 deletions
58
...nMain/kotlin/mikufan/cx/conduit/frontend/logic/component/main/me/EditProfile.component.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 |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package mikufan.cx.conduit.frontend.logic.component.main.me | ||
|
||
import com.arkivanov.decompose.ComponentContext | ||
import com.arkivanov.essenty.lifecycle.coroutines.coroutineScope | ||
import com.arkivanov.mvikotlin.core.instancekeeper.getStore | ||
import com.arkivanov.mvikotlin.extensions.coroutines.labels | ||
import com.arkivanov.mvikotlin.extensions.coroutines.stateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.launch | ||
import mikufan.cx.conduit.frontend.logic.component.util.MviComponent | ||
|
||
interface EditProfileComponent : MviComponent<EditProfileIntent, EditProfileState> | ||
|
||
class DefaultEditProfileComponent( | ||
initialState: EditProfileState, | ||
componentContext: ComponentContext, | ||
editProfileStoreFactory: EditProfileStoreFactory, | ||
private val onSaveSuccess: () -> Unit, | ||
) : EditProfileComponent, ComponentContext by componentContext { | ||
|
||
private val store = instanceKeeper.getStore { editProfileStoreFactory.createStore(initialState) } | ||
|
||
override val state: StateFlow<EditProfileState> = store.stateFlow(coroutineScope()) | ||
|
||
override fun send(intent: EditProfileIntent) = store.accept(intent) | ||
|
||
init { | ||
coroutineScope().launch { | ||
store.labels.collect { | ||
when (it) { | ||
is EditProfileLabel.SaveSuccessLabel -> onSaveSuccess() | ||
is EditProfileLabel.Unit -> Unit // do nothing as this label is just for test purpose | ||
} | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
class EditProfileComponentFactory( | ||
private val editProfileStoreFactory: EditProfileStoreFactory, | ||
) { | ||
fun create( | ||
componentContext: ComponentContext, | ||
loadedMe: LoadedMe, | ||
onSaveSuccess: () -> Unit, | ||
): EditProfileComponent = DefaultEditProfileComponent( | ||
initialState = EditProfileState( | ||
email = loadedMe.email, | ||
username = loadedMe.username, | ||
bio = loadedMe.bio, | ||
imageUrl = loadedMe.imageUrl, | ||
), | ||
componentContext = componentContext, | ||
editProfileStoreFactory = editProfileStoreFactory, | ||
onSaveSuccess = onSaveSuccess, | ||
) | ||
} |
36 changes: 36 additions & 0 deletions
36
...ommonMain/kotlin/mikufan/cx/conduit/frontend/logic/component/main/me/EditProfile.model.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 |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package mikufan.cx.conduit.frontend.logic.component.main.me | ||
|
||
data class EditProfileState( | ||
val email: String, | ||
val username: String, | ||
val bio: String, | ||
val imageUrl: String, | ||
/** | ||
* use null to indicate no change to password | ||
*/ | ||
val password: String? = null, | ||
) { | ||
init { | ||
if (password != null) { | ||
require(password.isNotEmpty()) { "Password cannot be empty" } | ||
} | ||
} | ||
} | ||
|
||
sealed interface EditProfileIntent { | ||
data class EmailChanged(val email: String) : EditProfileIntent | ||
data class UsernameChanged(val username: String) : EditProfileIntent | ||
data class BioChanged(val bio: String) : EditProfileIntent | ||
data class ImageUrlChanged(val imageUrl: String) : EditProfileIntent | ||
data class PasswordChanged(val password: String) : EditProfileIntent | ||
data object Save : EditProfileIntent | ||
} | ||
|
||
sealed interface EditProfileLabel { | ||
data object SaveSuccessLabel : EditProfileLabel | ||
/** | ||
* Just for test purpose | ||
*/ | ||
data object Unit : EditProfileLabel | ||
} | ||
|
64 changes: 64 additions & 0 deletions
64
...ommonMain/kotlin/mikufan/cx/conduit/frontend/logic/component/main/me/EditProfile.store.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 |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package mikufan.cx.conduit.frontend.logic.component.main.me | ||
|
||
import com.arkivanov.mvikotlin.core.store.Reducer | ||
import com.arkivanov.mvikotlin.core.store.StoreFactory | ||
import com.arkivanov.mvikotlin.extensions.coroutines.coroutineExecutorFactory | ||
import kotlinx.coroutines.CoroutineDispatcher | ||
import kotlinx.coroutines.Dispatchers | ||
|
||
class EditProfileStoreFactory( | ||
private val storeFactory: StoreFactory, | ||
private val mainDispatcher: CoroutineDispatcher = Dispatchers.Main, | ||
) { | ||
|
||
private val executorFactory = coroutineExecutorFactory<EditProfileIntent, Nothing, EditProfileState, Msg, EditProfileLabel>(mainDispatcher) { | ||
onIntent<EditProfileIntent.EmailChanged> { | ||
dispatch(Msg.EmailChanged(it.email)) | ||
} | ||
|
||
onIntent<EditProfileIntent.UsernameChanged> { | ||
dispatch(Msg.UsernameChanged(it.username)) | ||
} | ||
|
||
onIntent<EditProfileIntent.BioChanged> { | ||
dispatch(Msg.BioChanged(it.bio)) | ||
} | ||
|
||
onIntent<EditProfileIntent.ImageUrlChanged> { | ||
dispatch(Msg.ImageUrlChanged(it.imageUrl)) | ||
} | ||
|
||
onIntent<EditProfileIntent.PasswordChanged> { | ||
dispatch(Msg.PasswordChanged(it.password)) | ||
} | ||
|
||
onIntent<EditProfileIntent.Save> { | ||
TODO("Send put request and check result") | ||
} | ||
} | ||
|
||
private val reducer: Reducer<EditProfileState, Msg> = Reducer { msg -> | ||
when (msg) { | ||
is Msg.EmailChanged -> this.copy(email = msg.email) | ||
is Msg.UsernameChanged -> this.copy(username = msg.username) | ||
is Msg.BioChanged -> this.copy(bio = msg.bio) | ||
is Msg.ImageUrlChanged -> this.copy(imageUrl = msg.imageUrl) | ||
is Msg.PasswordChanged -> this.copy(password = msg.password) | ||
} | ||
} | ||
|
||
fun createStore(initialState: EditProfileState) = storeFactory.create( | ||
name = "EditProfileStore", | ||
initialState = initialState, | ||
executorFactory = executorFactory, | ||
reducer = reducer | ||
) | ||
|
||
private sealed interface Msg { | ||
data class EmailChanged(val email: String) : Msg | ||
data class UsernameChanged(val username: String) : Msg | ||
data class BioChanged(val bio: String) : Msg | ||
data class ImageUrlChanged(val imageUrl: String) : Msg | ||
data class PasswordChanged(val password: String) : Msg | ||
} | ||
} |
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
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