From d024e25f6acd0be1175b73b81b4639a322d90fb9 Mon Sep 17 00:00:00 2001 From: stslex Date: Fri, 4 Aug 2023 08:09:08 +0300 Subject: [PATCH] ad K2, base ui for userlist --- .../stslex/aproselection/SelectApplication.kt | 2 + .../ComposeAndroid.kt | 2 +- .../com.stslex.aproselection/KotlinAndroid.kt | 4 +- .../core/datastore/AppDataStore.kt | 2 + .../core/datastore/AppDataStoreImpl.kt | 5 + .../clients/user/UserNetworkClientImpl.kt | 12 +- .../core/ui/base/BaseViewModel.kt | 32 +++++- .../aproselection/core/ui/theme/AppDimens.kt | 1 + .../core/user/data/model/UserData.kt | 7 ++ .../core/user/data/model/UserMapper.kt | 16 +++ .../core/user/data/model/UserUpdateData.kt | 5 + .../user/data/repository/UserRepository.kt | 14 +++ .../data/repository/UserRepositoryImpl.kt | 29 +++++ .../core/user/di/ModuleCoreUser.kt | 11 ++ .../feature/home/di/ModuleFeatureHome.kt | 5 + ...eScreenInteractor.kt => HomeInteractor.kt} | 4 +- .../feature/home/domain/HomeInteractorImpl.kt | 28 +++++ .../feature/home/domain/model/HomeMapper.kt | 9 ++ .../feature/home/ui/HomeScreen.kt | 108 +++++++++++++++++- .../feature/home/ui/HomeViewModel.kt | 34 +++++- .../feature/home/ui/model/HomeUiMapper.kt | 9 ++ .../feature/home/ui/navigation/HomeRouter.kt | 5 +- gradle.properties | 12 +- gradle/libs.versions.toml | 2 +- 24 files changed, 334 insertions(+), 24 deletions(-) create mode 100644 core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserData.kt create mode 100644 core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserMapper.kt create mode 100644 core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserUpdateData.kt create mode 100644 core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepository.kt create mode 100644 core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepositoryImpl.kt create mode 100644 core/user/src/main/java/com/stslex/aproselection/core/user/di/ModuleCoreUser.kt rename feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/{HomeScreenInteractor.kt => HomeInteractor.kt} (78%) create mode 100644 feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractorImpl.kt create mode 100644 feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/model/HomeMapper.kt create mode 100644 feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/model/HomeUiMapper.kt diff --git a/app/src/main/java/com/stslex/aproselection/SelectApplication.kt b/app/src/main/java/com/stslex/aproselection/SelectApplication.kt index 2f4dc44..785ccb7 100644 --- a/app/src/main/java/com/stslex/aproselection/SelectApplication.kt +++ b/app/src/main/java/com/stslex/aproselection/SelectApplication.kt @@ -4,6 +4,7 @@ import android.app.Application import com.stslex.aproselection.controller.AuthController import com.stslex.aproselection.core.datastore.coreDataStoreModule import com.stslex.aproselection.core.network.di.ModuleCoreNetwork.moduleCoreNetwork +import com.stslex.aproselection.core.user.di.moduleCoreUser import com.stslex.aproselection.di.appModule import com.stslex.aproselection.feature.auth.di.ModuleFeatureAuth.moduleFeatureAuth import com.stslex.aproselection.feature.home.di.moduleFeatureHome @@ -33,6 +34,7 @@ class SelectApplication : Application() { modules( appModule, moduleCoreNetwork, + moduleCoreUser, coreDataStoreModule, moduleFeatureAuth, moduleFeatureHome, diff --git a/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/ComposeAndroid.kt b/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/ComposeAndroid.kt index 7038881..5c12cee 100644 --- a/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/ComposeAndroid.kt +++ b/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/ComposeAndroid.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile * Configure Compose-specific options */ internal fun Project.configureAndroidCompose( - commonExtension: CommonExtension<*, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *>, ) { val libs = extensions.getByType().named("libs") diff --git a/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/KotlinAndroid.kt b/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/KotlinAndroid.kt index e268996..9f65064 100644 --- a/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/KotlinAndroid.kt +++ b/build-logic/dependencies/src/main/kotlin/com.stslex.aproselection/KotlinAndroid.kt @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile * Configure base Kotlin with Android options */ internal fun Project.configureKotlinAndroid( - commonExtension: CommonExtension<*, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *>, ) { commonExtension.apply { @@ -64,7 +64,7 @@ internal fun Project.configureKotlinAndroid( } } -private fun CommonExtension<*, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) { +private fun CommonExtension<*, *, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) { (this as ExtensionAware).extensions.configure("kotlinOptions", block) } diff --git a/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStore.kt b/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStore.kt index 03f651d..727db75 100644 --- a/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStore.kt +++ b/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStore.kt @@ -10,4 +10,6 @@ interface AppDataStore { suspend fun setUuid(uuid: String) suspend fun setToken(token: String) + + suspend fun clear() } \ No newline at end of file diff --git a/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStoreImpl.kt b/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStoreImpl.kt index 87c2d8a..ee80359 100644 --- a/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStoreImpl.kt +++ b/core/datastore/src/main/java/com/stslex/aproselection/core/datastore/AppDataStoreImpl.kt @@ -50,4 +50,9 @@ class AppDataStoreImpl( } } } + + override suspend fun clear() { + setUuid("") + setToken("") + } } \ No newline at end of file diff --git a/core/network/src/main/java/com/stslex/aproselection/core/network/clients/user/UserNetworkClientImpl.kt b/core/network/src/main/java/com/stslex/aproselection/core/network/clients/user/UserNetworkClientImpl.kt index c95f622..86bc5c8 100644 --- a/core/network/src/main/java/com/stslex/aproselection/core/network/clients/user/UserNetworkClientImpl.kt +++ b/core/network/src/main/java/com/stslex/aproselection/core/network/clients/user/UserNetworkClientImpl.kt @@ -3,12 +3,12 @@ package com.stslex.aproselection.core.network.clients.user import com.stslex.aproselection.core.network.client.NetworkClient import com.stslex.aproselection.core.network.clients.user.model.UpdateUserInfoBody import com.stslex.aproselection.core.network.clients.user.model.UserResponse -import com.stslex.aproselection.core.network.model.PagingRequest import io.ktor.client.call.body import io.ktor.client.request.get import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.http.appendPathSegments +import io.ktor.util.AttributeKey import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -22,12 +22,10 @@ class UserNetworkClientImpl( ): List = withContext(Dispatchers.IO) { networkClient.apiClient.get { url.appendPathSegments("user", "list") - setBody( - PagingRequest( - pageNumber = page, - pageSize = pageSize - ) - ) + setAttributes { + put(AttributeKey("page_size"), pageSize) + put(AttributeKey("page_number"), page) + } }.body() } diff --git a/core/ui/src/main/java/com/stslex/aproselection/core/ui/base/BaseViewModel.kt b/core/ui/src/main/java/com/stslex/aproselection/core/ui/base/BaseViewModel.kt index 51832ab..ac46c9e 100644 --- a/core/ui/src/main/java/com/stslex/aproselection/core/ui/base/BaseViewModel.kt +++ b/core/ui/src/main/java/com/stslex/aproselection/core/ui/base/BaseViewModel.kt @@ -1,15 +1,33 @@ package com.stslex.aproselection.core.ui.base -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import androidx.paging.Pager +import androidx.paging.PagingData +import androidx.paging.cachedIn +import androidx.paging.map +import com.stslex.aproselection.core.core.Logger +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn open class BaseViewModel : ViewModel() { + inline fun Pager.mapState( + crossinline transform: suspend (T) -> R + ): StateFlow> = this + .flow + .map { pagingData -> + pagingData.map { item -> + transform(item) + } + } + .primaryPagingFlow + fun Flow.stateIn( initialValue: T ): StateFlow = this.stateIn( @@ -18,7 +36,17 @@ open class BaseViewModel : ViewModel() { initialValue = initialValue ) + val Flow>.primaryPagingFlow: StateFlow> + get() = cachedIn(viewModelScope) + .makeStateFlow(PagingData.empty()) + + private fun Flow.makeStateFlow(initialValue: T): StateFlow = + flowOn(Dispatchers.IO) + .stateIn( + initialValue = initialValue + ) + fun handleError(throwable: Throwable) { - Log.e(javaClass.simpleName, throwable.message, throwable) + Logger.exception(throwable) } } \ No newline at end of file diff --git a/core/ui/src/main/java/com/stslex/aproselection/core/ui/theme/AppDimens.kt b/core/ui/src/main/java/com/stslex/aproselection/core/ui/theme/AppDimens.kt index 2a967b9..365ae3b 100644 --- a/core/ui/src/main/java/com/stslex/aproselection/core/ui/theme/AppDimens.kt +++ b/core/ui/src/main/java/com/stslex/aproselection/core/ui/theme/AppDimens.kt @@ -10,6 +10,7 @@ object AppDimens { val small = 8.dp val medium = 16.dp val big = 32.dp + val large = 64.dp } object Corners { diff --git a/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserData.kt b/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserData.kt new file mode 100644 index 0000000..f331751 --- /dev/null +++ b/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserData.kt @@ -0,0 +1,7 @@ +package com.stslex.aproselection.core.user.data.model + +data class UserData( + val uuid: String, + val username: String, + val nickname: String +) diff --git a/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserMapper.kt b/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserMapper.kt new file mode 100644 index 0000000..1298ca5 --- /dev/null +++ b/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserMapper.kt @@ -0,0 +1,16 @@ +package com.stslex.aproselection.core.user.data.model + +import com.stslex.aproselection.core.network.clients.user.model.UpdateUserInfoBody +import com.stslex.aproselection.core.network.clients.user.model.UserResponse + +fun List.toData() = map { user -> + user.toData() +} + +fun UserResponse.toData() = UserData( + uuid = uuid, + username = username, + nickname = nickname +) + +fun UserUpdateData.toBody() = UpdateUserInfoBody(nickname) \ No newline at end of file diff --git a/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserUpdateData.kt b/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserUpdateData.kt new file mode 100644 index 0000000..85d8b97 --- /dev/null +++ b/core/user/src/main/java/com/stslex/aproselection/core/user/data/model/UserUpdateData.kt @@ -0,0 +1,5 @@ +package com.stslex.aproselection.core.user.data.model + +data class UserUpdateData( + val nickname: String +) diff --git a/core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepository.kt b/core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepository.kt new file mode 100644 index 0000000..4068b03 --- /dev/null +++ b/core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepository.kt @@ -0,0 +1,14 @@ +package com.stslex.aproselection.core.user.data.repository + +import com.stslex.aproselection.core.network.clients.user.model.UpdateUserInfoBody +import com.stslex.aproselection.core.user.data.model.UserData +import com.stslex.aproselection.core.user.data.model.UserUpdateData + +interface UserRepository { + + suspend fun getUserList(page: Int, pageSize: Int): List + + suspend fun getUser(uuid: String): UserData + + suspend fun updateUserInfo(info: UserUpdateData): UserData +} \ No newline at end of file diff --git a/core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepositoryImpl.kt b/core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepositoryImpl.kt new file mode 100644 index 0000000..eb9b02a --- /dev/null +++ b/core/user/src/main/java/com/stslex/aproselection/core/user/data/repository/UserRepositoryImpl.kt @@ -0,0 +1,29 @@ +package com.stslex.aproselection.core.user.data.repository + +import com.stslex.aproselection.core.network.clients.user.UserNetworkClient +import com.stslex.aproselection.core.user.data.model.UserData +import com.stslex.aproselection.core.user.data.model.UserUpdateData +import com.stslex.aproselection.core.user.data.model.toBody +import com.stslex.aproselection.core.user.data.model.toData + +class UserRepositoryImpl( + private val networkClient: UserNetworkClient +) : UserRepository { + + override suspend fun getUserList( + page: Int, + pageSize: Int + ): List = networkClient + .getUserList( + page = page, + pageSize = pageSize + ).toData() + + override suspend fun getUser( + uuid: String + ): UserData = networkClient.getUser(uuid).toData() + + override suspend fun updateUserInfo( + info: UserUpdateData + ): UserData = networkClient.updateUserInfo(info.toBody()).toData() +} \ No newline at end of file diff --git a/core/user/src/main/java/com/stslex/aproselection/core/user/di/ModuleCoreUser.kt b/core/user/src/main/java/com/stslex/aproselection/core/user/di/ModuleCoreUser.kt new file mode 100644 index 0000000..64a65cb --- /dev/null +++ b/core/user/src/main/java/com/stslex/aproselection/core/user/di/ModuleCoreUser.kt @@ -0,0 +1,11 @@ +package com.stslex.aproselection.core.user.di + +import com.stslex.aproselection.core.user.data.repository.UserRepository +import com.stslex.aproselection.core.user.data.repository.UserRepositoryImpl +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +val moduleCoreUser = module { + singleOf(::UserRepositoryImpl) { bind() } +} \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/di/ModuleFeatureHome.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/di/ModuleFeatureHome.kt index 8a944de..eeddca5 100644 --- a/feature/home/src/main/java/com/stslex/aproselection/feature/home/di/ModuleFeatureHome.kt +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/di/ModuleFeatureHome.kt @@ -1,9 +1,14 @@ package com.stslex.aproselection.feature.home.di +import com.stslex.aproselection.feature.home.domain.HomeInteractor +import com.stslex.aproselection.feature.home.domain.HomeInteractorImpl import com.stslex.aproselection.feature.home.ui.HomeViewModel import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf import org.koin.dsl.module val moduleFeatureHome = module { viewModelOf(::HomeViewModel) + singleOf(::HomeInteractorImpl) { bind() } } \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeScreenInteractor.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractor.kt similarity index 78% rename from feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeScreenInteractor.kt rename to feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractor.kt index a63726b..112cb8c 100644 --- a/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeScreenInteractor.kt +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractor.kt @@ -2,7 +2,9 @@ package com.stslex.aproselection.feature.home.domain import com.stslex.aproselection.feature.home.domain.model.UserDomain -interface HomeScreenInteractor { +interface HomeInteractor { suspend fun getAllUsers(page: Int, pageSize: Int): List + + suspend fun logOut() } \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractorImpl.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractorImpl.kt new file mode 100644 index 0000000..8c4de69 --- /dev/null +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/HomeInteractorImpl.kt @@ -0,0 +1,28 @@ +package com.stslex.aproselection.feature.home.domain + +import com.stslex.aproselection.core.datastore.AppDataStore +import com.stslex.aproselection.core.user.data.repository.UserRepository +import com.stslex.aproselection.feature.home.domain.model.UserDomain +import com.stslex.aproselection.feature.home.domain.model.toDomain + +class HomeInteractorImpl( + private val repository: UserRepository, + private val appDataStore: AppDataStore, +) : HomeInteractor { + + override suspend fun getAllUsers( + page: Int, + pageSize: Int + ): List = repository + .getUserList( + page = page, + pageSize = pageSize + ) + .map { user -> + user.toDomain() + } + + override suspend fun logOut() { + appDataStore.clear() + } +} \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/model/HomeMapper.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/model/HomeMapper.kt new file mode 100644 index 0000000..4a7a6d4 --- /dev/null +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/domain/model/HomeMapper.kt @@ -0,0 +1,9 @@ +package com.stslex.aproselection.feature.home.domain.model + +import com.stslex.aproselection.core.user.data.model.UserData + +fun UserData.toDomain() = UserDomain( + uuid = uuid, + username = username, + nickname = nickname +) \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeScreen.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeScreen.kt index f2d1bbb..8deb980 100644 --- a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeScreen.kt +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeScreen.kt @@ -1,25 +1,54 @@ package com.stslex.aproselection.feature.home.ui +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.material3.ElevatedButton +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Face +import androidx.compose.material3.ElevatedCard +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.paging.PagingData +import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.collectAsLazyPagingItems +import androidx.paging.compose.itemContentType +import androidx.paging.compose.itemKey +import com.stslex.aproselection.core.ui.theme.AppDimens +import com.stslex.aproselection.feature.home.ui.model.UserUi +import kotlinx.coroutines.flow.StateFlow +import kotlin.reflect.KProperty0 @Composable fun HomeScreen( logOut: () -> Unit, + users: KProperty0>>, modifier: Modifier = Modifier ) { + var isUsersOpen by remember { + mutableStateOf(false) + } + Box( modifier = modifier .fillMaxSize() @@ -41,5 +70,82 @@ fun HomeScreen( Text(text = "logout") } } + + AnimatedVisibility( + visible = isUsersOpen + ) { + val lazyPagingItems = remember { + users() + }.collectAsLazyPagingItems() + + Dialog( + onDismissRequest = { + isUsersOpen = false + }, + ) { + SelectUsersList( + users = lazyPagingItems + ) + } + } + + + AnimatedVisibility( + modifier = Modifier + .align(Alignment.BottomEnd), + visible = isUsersOpen.not() + ) { + FloatingActionButton( + modifier = Modifier.padding(AppDimens.Padding.medium), + onClick = { + isUsersOpen = true + } + ) { + Icon( + imageVector = Icons.Default.Add, + contentDescription = null + ) + } + } } +} + +@Composable +fun SelectUsersList( + users: LazyPagingItems, + modifier: Modifier = Modifier +) { + ElevatedCard( + modifier = modifier + .fillMaxSize() + .padding( + vertical = AppDimens.Padding.large, + horizontal = AppDimens.Padding.medium + ) + ) { + LazyColumn( + ) { + items( + count = users.itemCount, + contentType = users.itemContentType { "user" }, + key = users.itemKey { it.uuid } + ) { index -> + val user = users[index] + val userTitle = user?.let { + it.nickname.ifBlank { it.username } + }.orEmpty() + Row { + Icon( + imageVector = Icons.Default.Face, + contentDescription = null + ) + Spacer(modifier = Modifier.width(AppDimens.Padding.big)) + Text( + text = userTitle + ) + } + } + } + } + } \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeViewModel.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeViewModel.kt index 2459951..68c98de 100644 --- a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeViewModel.kt +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/HomeViewModel.kt @@ -1,18 +1,40 @@ package com.stslex.aproselection.feature.home.ui -import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.stslex.aproselection.core.datastore.AppDataStore +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import com.stslex.aproselection.core.ui.base.BasePagingSource +import com.stslex.aproselection.core.ui.base.BaseViewModel +import com.stslex.aproselection.feature.home.domain.HomeInteractor +import com.stslex.aproselection.feature.home.ui.model.UserUi +import com.stslex.aproselection.feature.home.ui.model.toPresentation +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch class HomeViewModel( - private val appDataStore: AppDataStore, -) : ViewModel() { + private val interactor: HomeInteractor +) : BaseViewModel() { + + val users: StateFlow> + get() = Pager(config = config) { + BasePagingSource(interactor::getAllUsers) + } + .mapState { user -> + user.toPresentation() + } fun logOut() { viewModelScope.launch { - appDataStore.setToken("") - appDataStore.setUuid("") + interactor.logOut() } } + + companion object { + + private val config = PagingConfig( + pageSize = 10, + enablePlaceholders = false + ) + } } \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/model/HomeUiMapper.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/model/HomeUiMapper.kt new file mode 100644 index 0000000..30cd2e3 --- /dev/null +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/model/HomeUiMapper.kt @@ -0,0 +1,9 @@ +package com.stslex.aproselection.feature.home.ui.model + +import com.stslex.aproselection.feature.home.domain.model.UserDomain + +fun UserDomain.toPresentation() = UserUi( + uuid = uuid, + username = username, + nickname = nickname +) \ No newline at end of file diff --git a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/navigation/HomeRouter.kt b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/navigation/HomeRouter.kt index ad3ec71..89a4aa2 100644 --- a/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/navigation/HomeRouter.kt +++ b/feature/home/src/main/java/com/stslex/aproselection/feature/home/ui/navigation/HomeRouter.kt @@ -1,9 +1,9 @@ package com.stslex.aproselection.feature.home.ui.navigation +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable -import com.stslex.aproselection.core.navigation.destination.AppDestination import com.stslex.aproselection.feature.home.ui.HomeScreen import com.stslex.aproselection.feature.home.ui.HomeViewModel import org.koin.androidx.compose.koinViewModel @@ -18,7 +18,8 @@ fun NavGraphBuilder.homeRouter( HomeScreen( modifier = modifier, - logOut = viewModel::logOut + logOut = viewModel::logOut, + users = remember { viewModel::users } ) } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3c5031e..3eb0718 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,14 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true + +# Use latest lint alpha for best available K2 support +# https://googlesamples.github.io/android-custom-lint-rules/usage/newer-lint.md.html +android.experimental.lint.version=8.2.0-alpha14 + +# Use K2 compiler +kotlin.experimental.tryK2=true + +# Run lint on K2 +android.lint.useK2Uast=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9241798..7c9bbe8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ androidDesugarJdkLibs = "2.0.3" kotlin = "1.9.0" kotlinLanguage = "1.9" -androidGradlePlugin = "8.0.2" +androidGradlePlugin = "8.1.0" ktx = "1.10.1" material = "1.9.0"