diff --git a/build-logic/src/main/kotlin/feature-module.gradle.kts b/build-logic/src/main/kotlin/feature-module.gradle.kts index 96c9238..38cb227 100644 --- a/build-logic/src/main/kotlin/feature-module.gradle.kts +++ b/build-logic/src/main/kotlin/feature-module.gradle.kts @@ -8,16 +8,11 @@ android { composeOptions { kotlinCompilerExtensionVersion = libs.versionStr("compose.compiler") } - - // It solve the issue with testing Coroutines Flow / ViewModel state - // and getting the error "app.cash.turbine.TurbineAssertionError: No value produced in 3s" - testOptions { - unitTests.isReturnDefaultValues = true - } } dependencies { implementation(project(":core:ui")) implementation(project(":core:di")) implementation(project(":core:domain")) + implementation(project(":core:coroutines")) } \ No newline at end of file diff --git a/core/di/build.gradle.kts b/core/di/build.gradle.kts index 51400ff..0e2a775 100644 --- a/core/di/build.gradle.kts +++ b/core/di/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("core-module") + id("core-compose-module") } dependencies { diff --git a/core/di/src/main/kotlin/com/mobiledevpro/di/KoinExt.kt b/core/di/src/main/kotlin/com/mobiledevpro/di/KoinExt.kt index 4da052b..17bf6e3 100644 --- a/core/di/src/main/kotlin/com/mobiledevpro/di/KoinExt.kt +++ b/core/di/src/main/kotlin/com/mobiledevpro/di/KoinExt.kt @@ -17,16 +17,37 @@ */ package com.mobiledevpro.di +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisallowComposableCalls +import androidx.compose.runtime.remember +import org.koin.compose.module.rememberKoinModules +import org.koin.compose.scope.rememberKoinScope +import org.koin.core.annotation.KoinExperimentalAPI +import org.koin.core.module.Module import org.koin.core.qualifier.TypeQualifier import org.koin.core.scope.Scope import org.koin.ext.getFullName import org.koin.java.KoinJavaComponent -inline fun koinScope(): Scope { +inline fun koinScope(): Scope { val scopeId = T::class.getFullName() + "@" + T::class.hashCode() val qualifier = TypeQualifier(T::class) return KoinJavaComponent.getKoin().getOrCreateScope(scopeId, qualifier) +} + +@OptIn(KoinExperimentalAPI::class) +@Composable +inline fun rememberViewModel( + crossinline modules: @DisallowComposableCalls () -> List +): T { + rememberKoinModules( + modules = modules + ) + + val scope = rememberKoinScope(scope = koinScope()) + + return remember { scope.get() } } \ No newline at end of file diff --git a/core/navigation/src/main/kotlin/com/mobiledevpro/navigation/ScreenNavigation.kt b/core/navigation/src/main/kotlin/com/mobiledevpro/navigation/ScreenNavigation.kt index 1247743..4214a75 100644 --- a/core/navigation/src/main/kotlin/com/mobiledevpro/navigation/ScreenNavigation.kt +++ b/core/navigation/src/main/kotlin/com/mobiledevpro/navigation/ScreenNavigation.kt @@ -28,9 +28,10 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument +import com.mobiledevpro.chatlist.di.featureChatListModule import com.mobiledevpro.chatlist.view.ChatListScreen import com.mobiledevpro.chatlist.view.ChatListViewModel -import com.mobiledevpro.di.koinScope +import com.mobiledevpro.di.rememberViewModel import com.mobiledevpro.home.view.HomeScreen import com.mobiledevpro.home.view.HomeViewModel import com.mobiledevpro.navigation.ext.navigateTo @@ -45,13 +46,13 @@ import com.mobiledevpro.people.profile.view.PeopleProfileScreen import com.mobiledevpro.people.profile.view.PeopleProfileViewModel import com.mobiledevpro.people.profile.view.args.PeopleProfileArgs import com.mobiledevpro.people.view.PeopleScreen +import com.mobiledevpro.peoplelist.di.featurePeopleListModule import com.mobiledevpro.peoplelist.view.PeopleListScreen import com.mobiledevpro.peoplelist.view.PeopleListViewModel import com.mobiledevpro.subscription.SubscriptionScreen import com.mobiledevpro.user.profile.di.featureUserProfileModule import com.mobiledevpro.user.profile.view.ProfileScreen import com.mobiledevpro.user.profile.view.vm.ProfileViewModel -import org.koin.core.context.loadKoinModules fun NavGraphBuilder.homeNavGraph(onNavigateToRoot: (Screen) -> Unit) { @@ -179,7 +180,9 @@ fun NavGraphBuilder.chatListScreen() { route = Screen.ChatList.route ) { - val viewModel: ChatListViewModel = viewModel() + val viewModel = rememberViewModel( + modules = { listOf(featureChatListModule) } + ) ChatListScreen( state = viewModel.uiState, @@ -195,7 +198,9 @@ fun NavGraphBuilder.peopleListScreen(onNavigateTo: (Screen) -> Unit) { route = Screen.PeopleList.route ) { - val viewModel: PeopleListViewModel = viewModel() + val viewModel = rememberViewModel( + modules = { listOf(featurePeopleListModule) } + ) PeopleListScreen( viewModel.uiState, @@ -237,8 +242,11 @@ fun NavGraphBuilder.profileScreen(onNavigateTo: (Screen) -> Unit) { route = Screen.Profile.route ) { - loadKoinModules(featureUserProfileModule) - val viewModel: ProfileViewModel by koinScope().inject() + val viewModel = rememberViewModel( + modules = { + listOf(featureUserProfileModule) + } + ) ProfileScreen( state = viewModel.uiState, diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/local/ImplUserProfileLocalSource.kt b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/di/Module.kt similarity index 59% rename from feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/local/ImplUserProfileLocalSource.kt rename to feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/di/Module.kt index 3d416b0..ae76a72 100644 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/local/ImplUserProfileLocalSource.kt +++ b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/di/Module.kt @@ -15,16 +15,25 @@ * limitations under the License. * */ -package com.mobiledevpro.user.profile.data.local +package com.mobiledevpro.chatlist.di + +import com.mobiledevpro.chatlist.domain.usecase.GetChatListUseCase +import com.mobiledevpro.chatlist.view.ChatListViewModel +import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.scopedOf +import org.koin.dsl.module /** - * For User Profile screen + * User Profile screen module * * Created on Jul 22, 2023. * */ -class ImplUserProfileLocalSource( -) : UserProfileLocalSource { +val featureChatListModule = module { + scope { + viewModelOf(::ChatListViewModel) + scopedOf(::GetChatListUseCase) + } } \ No newline at end of file diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/repository/ImplUserProfileRepository.kt b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/domain/usecase/GetChatListUseCase.kt similarity index 53% rename from feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/repository/ImplUserProfileRepository.kt rename to feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/domain/usecase/GetChatListUseCase.kt index ace79c0..72af1d6 100644 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/repository/ImplUserProfileRepository.kt +++ b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/domain/usecase/GetChatListUseCase.kt @@ -15,18 +15,22 @@ * limitations under the License. * */ -package com.mobiledevpro.user.profile.data.repository +package com.mobiledevpro.chatlist.domain.usecase -import com.mobiledevpro.user.profile.data.local.UserProfileLocalSource +import com.mobiledevpro.coroutines.BaseCoroutinesFLowUseCase +import com.mobiledevpro.coroutines.None +import com.mobiledevpro.domain.model.Chat +import com.mobiledevpro.domain.model.fakeChatList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf -/** - * For User Profile screen - * - * Created on Jul 22, 2023. - * - */ -class ImplUserProfileRepository( - private val localSource: UserProfileLocalSource -) : UserProfileRepository { + +class GetChatListUseCase( + +) : BaseCoroutinesFLowUseCase, None>(Dispatchers.IO) { + + override fun buildUseCaseFlow(params: None?): Flow> = + flowOf(fakeChatList) } \ No newline at end of file diff --git a/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListUIState.kt b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListUIState.kt index 40bc75a..a94f7bd 100644 --- a/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListUIState.kt +++ b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListUIState.kt @@ -18,6 +18,7 @@ package com.mobiledevpro.chatlist.view import com.mobiledevpro.domain.model.Chat +import com.mobiledevpro.ui.state.UIState /** * UI state for [com.mobiledevpro.chatlist.view.ChatListScreen] @@ -25,11 +26,11 @@ import com.mobiledevpro.domain.model.Chat * Created on Feb 04, 2023. * */ -sealed interface ChatListUIState { +sealed interface ChatListUIState : UIState { - object Empty : ChatListUIState + data object Empty : ChatListUIState - object Loading : ChatListUIState + data object Loading : ChatListUIState class Success(val profileList : List) : ChatListUIState diff --git a/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListViewModel.kt b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListViewModel.kt index 2d960e4..a73c80c 100644 --- a/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListViewModel.kt +++ b/feature/chat_list/src/main/kotlin/com/mobiledevpro/chatlist/view/ChatListViewModel.kt @@ -17,40 +17,34 @@ */ package com.mobiledevpro.chatlist.view -import androidx.lifecycle.ViewModel +import android.util.Log import androidx.lifecycle.viewModelScope -import com.mobiledevpro.domain.model.fakeChatList -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch +import com.mobiledevpro.chatlist.domain.usecase.GetChatListUseCase +import com.mobiledevpro.ui.vm.BaseViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach -class ChatListViewModel : ViewModel() { - private val _uiState: MutableStateFlow = - MutableStateFlow(ChatListUIState.Empty) - val uiState: StateFlow = _uiState.asStateFlow() +class ChatListViewModel( + private val getChatListUseCase: GetChatListUseCase +) : BaseViewModel() { + + override fun initUIState(): ChatListUIState = ChatListUIState.Empty init { + Log.d("UI", "ChatListViewModel init") observeChatList() } private fun observeChatList() { - viewModelScope.launch { - - _uiState.update { ChatListUIState.Loading } - - // delay(1000) - - /* - _uiState.update { PeopleProfileUIState.Empty } - _uiState.update { PeopleProfileUIState.Fail(Throwable("Test error")) } - - */ - _uiState.update { - ChatListUIState.Success(fakeChatList) - } - } + getChatListUseCase.execute() + .onEach { result -> + result.onSuccess { list -> + ChatListUIState.Success(list) + .also { _uiState.value = it } + }.onFailure { + //TODO: show an error + } + }.launchIn(viewModelScope) } } \ No newline at end of file diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/interactor/ImplUserProfileInteractor.kt b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/di/Module.kt similarity index 58% rename from feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/interactor/ImplUserProfileInteractor.kt rename to feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/di/Module.kt index ad35300..ce47a2c 100644 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/interactor/ImplUserProfileInteractor.kt +++ b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/di/Module.kt @@ -15,18 +15,25 @@ * limitations under the License. * */ -package com.mobiledevpro.user.profile.domain.interactor +package com.mobiledevpro.peoplelist.di -import com.mobiledevpro.user.profile.data.repository.UserProfileRepository +import com.mobiledevpro.peoplelist.domain.usecase.GetPeopleListUseCase +import com.mobiledevpro.peoplelist.view.PeopleListViewModel +import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.scopedOf +import org.koin.dsl.module /** - * For User Profile screen + * User Profile screen module * * Created on Jul 22, 2023. * */ -class ImplUserProfileInteractor( - val repository: UserProfileRepository -) : UserProfileInteractor { +val featurePeopleListModule = module { + + scope { + viewModelOf(::PeopleListViewModel) + scopedOf(::GetPeopleListUseCase) + } } \ No newline at end of file diff --git a/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/domain/usecase/GetPeopleListUseCase.kt b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/domain/usecase/GetPeopleListUseCase.kt new file mode 100644 index 0000000..ef46f05 --- /dev/null +++ b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/domain/usecase/GetPeopleListUseCase.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2023 | Dmitri Chernysh | https://mobile-dev.pro + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.mobiledevpro.peoplelist.domain.usecase + +import com.mobiledevpro.coroutines.BaseCoroutinesFLowUseCase +import com.mobiledevpro.coroutines.None +import com.mobiledevpro.domain.model.PeopleProfile +import com.mobiledevpro.domain.model.fakePeopleProfileList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + + +class GetPeopleListUseCase( + +) : BaseCoroutinesFLowUseCase, None>(Dispatchers.IO) { + + override fun buildUseCaseFlow(params: None?): Flow> = + flowOf(fakePeopleProfileList) +} \ No newline at end of file diff --git a/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleListViewModel.kt b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleListViewModel.kt index 3e1bf08..eee1168 100644 --- a/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleListViewModel.kt +++ b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleListViewModel.kt @@ -17,41 +17,36 @@ */ package com.mobiledevpro.peoplelist.view -import androidx.lifecycle.ViewModel +import android.util.Log import androidx.lifecycle.viewModelScope -import com.mobiledevpro.domain.model.fakePeopleProfileList -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch +import com.mobiledevpro.peoplelist.domain.usecase.GetPeopleListUseCase +import com.mobiledevpro.ui.vm.BaseViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach -class PeopleListViewModel : ViewModel() { +class PeopleListViewModel( + private val getPeopleListUseCase: GetPeopleListUseCase +) : BaseViewModel() { - private val _uiState: MutableStateFlow = - MutableStateFlow(PeopleProfileUIState.Empty) - val uiState: StateFlow = _uiState.asStateFlow() + override fun initUIState(): PeopleProfileUIState = PeopleProfileUIState.Empty init { + Log.d("UI", "PeopleListViewModel init") observePeopleList() } private fun observePeopleList() { - viewModelScope.launch { - _uiState.update { PeopleProfileUIState.Loading } - - delay(2000) - - // _uiState.update { PeopleProfileUIState.Empty } - // _uiState.update { PeopleProfileUIState.Fail(Throwable("Test error")) } - - _uiState.update { - PeopleProfileUIState.Success(fakePeopleProfileList) - } - } + getPeopleListUseCase.execute() + .onEach { result -> + result.onSuccess { list -> + PeopleProfileUIState.Success(list) + .also { _uiState.value = it } + }.onFailure { + //TODO: show error + } + }.launchIn(viewModelScope) } } \ No newline at end of file diff --git a/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleProfileUIState.kt b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleProfileUIState.kt index b582e26..3011ebb 100644 --- a/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleProfileUIState.kt +++ b/feature/people_list/src/main/kotlin/com/mobiledevpro/peoplelist/view/PeopleProfileUIState.kt @@ -18,6 +18,7 @@ package com.mobiledevpro.peoplelist.view import com.mobiledevpro.domain.model.PeopleProfile +import com.mobiledevpro.ui.state.UIState /** * UI state for [com.mobiledevpro.peoplelist.view.PeopleListScreen] @@ -25,7 +26,7 @@ import com.mobiledevpro.domain.model.PeopleProfile * Created on Feb 04, 2023. * */ -sealed interface PeopleProfileUIState { +sealed interface PeopleProfileUIState : UIState { object Empty : PeopleProfileUIState diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/local/UserProfileLocalSource.kt b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/local/UserProfileLocalSource.kt deleted file mode 100644 index 9c1b2c9..0000000 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/local/UserProfileLocalSource.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 | Dmitri Chernysh | https://mobile-dev.pro - * - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package com.mobiledevpro.user.profile.data.local - -/** - * For User Profile screen - * - * Created on Jul 22, 2023. - * - */ -interface UserProfileLocalSource { -} \ No newline at end of file diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/di/Module.kt b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/di/Module.kt index 7247968..bd3b149 100644 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/di/Module.kt +++ b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/di/Module.kt @@ -17,14 +17,10 @@ */ package com.mobiledevpro.user.profile.di -import com.mobiledevpro.user.profile.data.local.ImplUserProfileLocalSource -import com.mobiledevpro.user.profile.data.local.UserProfileLocalSource -import com.mobiledevpro.user.profile.data.repository.ImplUserProfileRepository -import com.mobiledevpro.user.profile.data.repository.UserProfileRepository -import com.mobiledevpro.user.profile.domain.interactor.ImplUserProfileInteractor -import com.mobiledevpro.user.profile.domain.interactor.UserProfileInteractor +import com.mobiledevpro.user.profile.domain.usecase.GetUserProfileUseCase import com.mobiledevpro.user.profile.view.vm.ProfileViewModel import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.scopedOf import org.koin.dsl.module /** @@ -38,23 +34,6 @@ val featureUserProfileModule = module { scope { viewModelOf(::ProfileViewModel) - - scoped{ - ImplUserProfileInteractor( - repository = get() - ) - } - - scoped { - ImplUserProfileRepository( - localSource = get() - ) - } - - scoped { - ImplUserProfileLocalSource( - - ) - } + scopedOf(::GetUserProfileUseCase) } } \ No newline at end of file diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/interactor/UserProfileInteractor.kt b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/interactor/UserProfileInteractor.kt deleted file mode 100644 index c24a173..0000000 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/interactor/UserProfileInteractor.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 | Dmitri Chernysh | https://mobile-dev.pro - * - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package com.mobiledevpro.user.profile.domain.interactor - -/** - * For User Profile screen - * - * Created on Jul 22, 2023. - * - */ -interface UserProfileInteractor { -} \ No newline at end of file diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/repository/UserProfileRepository.kt b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/usecase/GetUserProfileUseCase.kt similarity index 53% rename from feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/repository/UserProfileRepository.kt rename to feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/usecase/GetUserProfileUseCase.kt index 91f2b9a..d920a4d 100644 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/data/repository/UserProfileRepository.kt +++ b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/domain/usecase/GetUserProfileUseCase.kt @@ -15,13 +15,21 @@ * limitations under the License. * */ -package com.mobiledevpro.user.profile.data.repository +package com.mobiledevpro.user.profile.domain.usecase -/** - * For User Profile screen - * - * Created on Jul 22, 2023. - * - */ -interface UserProfileRepository { +import com.mobiledevpro.coroutines.BaseCoroutinesFLowUseCase +import com.mobiledevpro.coroutines.None +import com.mobiledevpro.domain.model.UserProfile +import com.mobiledevpro.domain.model.fakeUser +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + + +class GetUserProfileUseCase( + +) : BaseCoroutinesFLowUseCase(Dispatchers.IO) { + + override fun buildUseCaseFlow(params: None?): Flow = + flowOf(fakeUser) } \ No newline at end of file diff --git a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/view/vm/ProfileViewModel.kt b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/view/vm/ProfileViewModel.kt index 19aaee7..09fbf1b 100644 --- a/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/view/vm/ProfileViewModel.kt +++ b/feature/user_profile/src/main/kotlin/com/mobiledevpro/user/profile/view/vm/ProfileViewModel.kt @@ -17,33 +17,35 @@ */ package com.mobiledevpro.user.profile.view.vm +import android.util.Log import androidx.lifecycle.viewModelScope -import com.mobiledevpro.domain.model.fakeUser import com.mobiledevpro.ui.vm.BaseViewModel -import com.mobiledevpro.user.profile.domain.interactor.UserProfileInteractor +import com.mobiledevpro.user.profile.domain.usecase.GetUserProfileUseCase import com.mobiledevpro.user.profile.view.state.UserProfileUIState -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class ProfileViewModel( - private val interactor: UserProfileInteractor + private val getUserProfileUseCase: GetUserProfileUseCase ) : BaseViewModel() { override fun initUIState(): UserProfileUIState = UserProfileUIState.Empty init { + Log.d("UI", "ProfileViewModel init") observeUserProfile() } private fun observeUserProfile() { - viewModelScope.launch { - - //TODO: call repository here - - - _uiState.update { - UserProfileUIState.Success(fakeUser) - } - } + getUserProfileUseCase.execute() + .onEach { result -> + result.onSuccess { profile -> + UserProfileUIState.Success(profile) + .also { _uiState.value = it } + }.onFailure { + //TODO: show the error + } + + }.launchIn(viewModelScope) } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index da80134..5769b44 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,14 +15,14 @@ kotlin-serialization = "1.4.1" # Libs android-core-ktx = "1.12.0" activity = "1.8.2" -navigation = "2.7.6" +navigation = "2.7.7" retrofit = "2.9.0" room = "2.4.3" lifecycle = "2.7.0" -compose-bom = "2024.01.00" +compose-bom = "2024.02.00" compose-compiler = "1.5.8" coil = "2.5.0" -material3 = "1.2.0-rc01" +material3 = "1.2.0" koin = "3.5.3" koin-compose = "3.5.3" coroutines-android = "1.7.3"