Skip to content

Commit

Permalink
Merge pull request #260 from ouchadam/tech/profile-reducer
Browse files Browse the repository at this point in the history
Porting ProfileViewModel to reducer
  • Loading branch information
ouchadam authored Nov 7, 2022
2 parents 5c4ff45 + aa19346 commit 8885406
Show file tree
Hide file tree
Showing 16 changed files with 358 additions and 182 deletions.
7 changes: 2 additions & 5 deletions chat-engine/src/testFixtures/kotlin/fake/FakeChatEngine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@ import java.io.InputStream
class FakeChatEngine : ChatEngine by mockk() {

fun givenMessages(roomId: RoomId, disableReadReceipts: Boolean) = every { messages(roomId, disableReadReceipts) }.delegateReturn()

fun givenDirectory() = every { directory() }.delegateReturn()

fun givenImportKeys(inputStream: InputStream, passphrase: String) = coEvery { inputStream.importRoomKeys(passphrase) }.delegateReturn()

fun givenNotificationsInvites() = every { notificationsInvites() }.delegateEmit()

fun givenNotificationsMessages() = every { notificationsMessages() }.delegateEmit()

fun givenInvites() = every { invites() }.delegateEmit()
fun givenMe(forceRefresh: Boolean) = coEvery { me(forceRefresh) }.delegateReturn()
}
4 changes: 4 additions & 0 deletions core/src/main/kotlin/app/dapk/st/core/JobBag.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ class JobBag {
jobs.remove(key.java.canonicalName)?.cancel()
}

fun cancelAll() {
jobs.values.forEach { it.cancel() }
}

}
2 changes: 0 additions & 2 deletions features/directory/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ applyAndroidComposeLibraryModule(project)
dependencies {
implementation project(":chat-engine")
implementation project(":domains:android:compose-core")
implementation project(":domains:android:viewmodel")
implementation project(":domains:state")
implementation project(":features:messenger")
implementation project(":core")
Expand All @@ -16,7 +15,6 @@ dependencies {
androidImportFixturesWorkaround(project, project(":core"))
androidImportFixturesWorkaround(project, project(":domains:state"))
androidImportFixturesWorkaround(project, project(":domains:store"))
androidImportFixturesWorkaround(project, project(":domains:android:viewmodel"))
androidImportFixturesWorkaround(project, project(":domains:android:stub"))
androidImportFixturesWorkaround(project, project(":chat-engine"))
}
6 changes: 3 additions & 3 deletions features/home/src/main/kotlin/app/dapk/st/home/HomeModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ import app.dapk.st.directory.state.DirectoryState
import app.dapk.st.domain.StoreModule
import app.dapk.st.engine.ChatEngine
import app.dapk.st.login.LoginViewModel
import app.dapk.st.profile.ProfileViewModel
import app.dapk.st.profile.state.ProfileState

class HomeModule(
private val chatEngine: ChatEngine,
private val storeModule: StoreModule,
val betaVersionUpgradeUseCase: BetaVersionUpgradeUseCase,
) : ProvidableModule {

internal fun homeViewModel(directory: DirectoryState, login: LoginViewModel, profileViewModel: ProfileViewModel): HomeViewModel {
internal fun homeViewModel(directory: DirectoryState, login: LoginViewModel, profile: ProfileState): HomeViewModel {
return HomeViewModel(
chatEngine,
storeModule.credentialsStore(),
directory,
login,
profileViewModel,
profile,
storeModule.cacheCleaner(),
betaVersionUpgradeUseCase,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import app.dapk.st.home.HomeScreenState.*
import app.dapk.st.login.LoginViewModel
import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.isSignedIn
import app.dapk.st.profile.ProfileViewModel
import app.dapk.st.profile.state.ProfileAction
import app.dapk.st.profile.state.ProfileState
import app.dapk.st.viewmodel.DapkViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
Expand All @@ -24,7 +25,7 @@ internal class HomeViewModel(
private val credentialsProvider: CredentialsStore,
private val directoryState: DirectoryState,
private val loginViewModel: LoginViewModel,
private val profileViewModel: ProfileViewModel,
private val profileState: ProfileState,
private val cacheCleaner: StoreCleaner,
private val betaVersionUpgradeUseCase: BetaVersionUpgradeUseCase,
) : DapkViewModel<HomeScreenState, HomeEvent>(
Expand All @@ -35,7 +36,7 @@ internal class HomeViewModel(

fun directory() = directoryState
fun login() = loginViewModel
fun profile() = profileViewModel
fun profile() = profileState

fun start() {
viewModelScope.launch {
Expand Down Expand Up @@ -125,7 +126,7 @@ internal class HomeViewModel(

Page.Profile -> {
directoryState.dispatch(ComponentLifecycle.OnGone)
profileViewModel.reset()
profileState.dispatch(ProfileAction.Reset)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MainActivity : DapkActivity() {

private val directoryViewModel by state { module<DirectoryModule>().directoryState() }
private val loginViewModel by viewModel { module<LoginModule>().loginViewModel() }
private val profileViewModel by viewModel { module<ProfileModule>().profileViewModel() }
private val profileViewModel by state { module<ProfileModule>().profileState() }
private val homeViewModel by viewModel { module<HomeModule>().homeViewModel(directoryViewModel, loginViewModel, profileViewModel) }

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down
11 changes: 10 additions & 1 deletion features/profile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ dependencies {
implementation project(":chat-engine")
implementation project(":features:settings")
implementation project(':domains:store')
implementation project(':domains:state')
implementation project(":domains:android:compose-core")
implementation project(":domains:android:viewmodel")
implementation project(":design-library")
implementation project(":core")

kotlinTest(it)

androidImportFixturesWorkaround(project, project(":matrix:common"))
androidImportFixturesWorkaround(project, project(":core"))
androidImportFixturesWorkaround(project, project(":domains:state"))
androidImportFixturesWorkaround(project, project(":domains:store"))
androidImportFixturesWorkaround(project, project(":domains:android:stub"))
androidImportFixturesWorkaround(project, project(":chat-engine"))
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package app.dapk.st.profile

import app.dapk.st.core.JobBag
import app.dapk.st.core.ProvidableModule
import app.dapk.st.core.createStateViewModel
import app.dapk.st.core.extensions.ErrorTracker
import app.dapk.st.engine.ChatEngine
import app.dapk.st.profile.state.ProfileState
import app.dapk.st.profile.state.ProfileUseCase
import app.dapk.st.profile.state.profileReducer

class ProfileModule(
private val chatEngine: ChatEngine,
private val errorTracker: ErrorTracker,
) : ProvidableModule {

fun profileViewModel(): ProfileViewModel {
return ProfileViewModel(chatEngine, errorTracker)
fun profileState(): ProfileState {
return createStateViewModel { profileReducer(chatEngine, errorTracker, ProfileUseCase(chatEngine, errorTracker), JobBag()) }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,34 @@ import androidx.compose.ui.unit.dp
import app.dapk.st.core.Lce
import app.dapk.st.core.LifecycleEffect
import app.dapk.st.core.components.CenteredLoading
import app.dapk.st.core.page.PageAction
import app.dapk.st.design.components.*
import app.dapk.st.engine.RoomInvite
import app.dapk.st.engine.RoomInvite.InviteMeta
import app.dapk.st.profile.state.Page
import app.dapk.st.profile.state.ProfileAction
import app.dapk.st.profile.state.ProfileState
import app.dapk.st.settings.SettingsActivity

@Composable
fun ProfileScreen(viewModel: ProfileViewModel, onTopLevelBack: () -> Unit) {
fun ProfileScreen(viewModel: ProfileState, onTopLevelBack: () -> Unit) {
viewModel.ObserveEvents()

LifecycleEffect(
onStart = { viewModel.start() },
onStop = { viewModel.stop() }
onStart = { viewModel.dispatch(ProfileAction.ComponentLifecycle.Visible) },
onStop = { viewModel.dispatch(ProfileAction.ComponentLifecycle.Gone) }
)

val context = LocalContext.current

val onNavigate: (SpiderPage<out Page>?) -> Unit = {
when (it) {
null -> onTopLevelBack()
else -> viewModel.goTo(it)
else -> viewModel.dispatch(PageAction.GoTo(it))
}
}

Spider(currentPage = viewModel.state.page, onNavigate = onNavigate) {
Spider(currentPage = viewModel.current.state1.page, onNavigate = onNavigate) {
item(Page.Routes.profile) {
ProfilePage(context, viewModel, it)
}
Expand All @@ -54,7 +58,7 @@ fun ProfileScreen(viewModel: ProfileViewModel, onTopLevelBack: () -> Unit) {
}

@Composable
private fun ProfilePage(context: Context, viewModel: ProfileViewModel, profile: Page.Profile) {
private fun ProfilePage(context: Context, viewModel: ProfileState, profile: Page.Profile) {
Box(
modifier = Modifier
.fillMaxWidth()
Expand All @@ -67,7 +71,7 @@ private fun ProfilePage(context: Context, viewModel: ProfileViewModel, profile:

when (val state = profile.content) {
is Lce.Loading -> CenteredLoading()
is Lce.Error -> GenericError { viewModel.start() }
is Lce.Error -> GenericError { viewModel.dispatch(ProfileAction.ComponentLifecycle.Visible) }
is Lce.Content -> {
val configuration = LocalConfiguration.current
val content = state.value
Expand Down Expand Up @@ -111,15 +115,15 @@ private fun ProfilePage(context: Context, viewModel: ProfileViewModel, profile:
TextRow(
title = "Invitations",
content = "${content.invitationsCount} pending",
onClick = { viewModel.goToInvitations() }
onClick = { viewModel.dispatch(ProfileAction.GoToInvitations) }
)
}
}
}
}

@Composable
private fun SpiderItemScope.Invitations(viewModel: ProfileViewModel, invitations: Page.Invitations) {
private fun SpiderItemScope.Invitations(viewModel: ProfileState, invitations: Page.Invitations) {
when (val state = invitations.content) {
is Lce.Loading -> CenteredLoading()
is Lce.Content -> {
Expand All @@ -133,11 +137,11 @@ private fun SpiderItemScope.Invitations(viewModel: ProfileViewModel, invitations
TextRow(title = text, includeDivider = false) {
Spacer(modifier = Modifier.height(4.dp))
Row {
Button(modifier = Modifier.weight(1f), onClick = { viewModel.rejectRoomInvite(it.roomId) }) {
Button(modifier = Modifier.weight(1f), onClick = { viewModel.dispatch(ProfileAction.RejectRoomInvite(it.roomId)) }) {
Text("Reject".uppercase())
}
Spacer(modifier = Modifier.fillMaxWidth(0.1f))
Button(modifier = Modifier.weight(1f), onClick = { viewModel.acceptRoomInvite(it.roomId) }) {
Button(modifier = Modifier.weight(1f), onClick = { viewModel.dispatch(ProfileAction.AcceptRoomInvite(it.roomId)) }) {
Text("Accept".uppercase())
}
}
Expand All @@ -154,7 +158,7 @@ private fun SpiderItemScope.Invitations(viewModel: ProfileViewModel, invitations
private fun RoomInvite.inviterName() = this.from.displayName?.let { "$it (${this.from.id.value})" } ?: this.from.id.value

@Composable
private fun ProfileViewModel.ObserveEvents() {
private fun ProfileState.ObserveEvents() {
// StartObserving {
// [email protected] {
// when (it) {
Expand Down
Loading

0 comments on commit 8885406

Please sign in to comment.