diff --git a/app/build.gradle b/app/build.gradle index 08de33e..1853774 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,10 +55,10 @@ android { } dependencies { - implementation 'androidx.core:core-ktx:1.12.0' - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0' - implementation 'androidx.activity:activity-compose:1.8.2' - implementation platform('androidx.compose:compose-bom:2024.03.00') + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.1' + implementation 'androidx.activity:activity-compose:1.9.0' + implementation platform('androidx.compose:compose-bom:2024.05.00') implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-tooling-preview' @@ -66,7 +66,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation platform('androidx.compose:compose-bom:2024.03.00') + androidTestImplementation platform('androidx.compose:compose-bom:2024.05.00') androidTestImplementation 'androidx.compose.ui:ui-test-junit4' debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-test-manifest' @@ -76,16 +76,19 @@ dependencies { //Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1' + implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3' implementation 'com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0' // define a BOM and its version - implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0")) + implementation(platform("com.squareup.okhttp3:okhttp-bom:4.11.0")) // define any required OkHttp artifacts without version implementation("com.squareup.okhttp3:okhttp") implementation("com.squareup.okhttp3:logging-interceptor") // Coil - implementation("io.coil-kt:coil-compose:2.4.0") + implementation("io.coil-kt:coil-compose:2.6.0") + + + implementation ("androidx.lifecycle:lifecycle-runtime-compose:2.8.1") } \ No newline at end of file diff --git a/app/src/androidTest/java/com/sopt/now/compose/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/sopt/now/compose/ExampleInstrumentedTest.kt index 72ca219..df74362 100644 --- a/app/src/androidTest/java/com/sopt/now/compose/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/sopt/now/compose/ExampleInstrumentedTest.kt @@ -1,13 +1,11 @@ package com.sopt.now.compose -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * diff --git a/app/src/main/java/com/sopt/now/compose/MainActivity.kt b/app/src/main/java/com/sopt/now/compose/MainActivity.kt index 3324d5a..581b114 100644 --- a/app/src/main/java/com/sopt/now/compose/MainActivity.kt +++ b/app/src/main/java/com/sopt/now/compose/MainActivity.kt @@ -1,32 +1,15 @@ package com.sopt.now.compose import android.content.Context -import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.sopt.now.compose.models.User import com.sopt.now.compose.ui.SoptApp -import com.sopt.now.compose.ui.composables.TitleAndContentTextComposable import com.sopt.now.compose.ui.theme.NOWSOPTAndroidTheme class MainActivity : ComponentActivity() { diff --git a/app/src/main/java/com/sopt/now/compose/SoptApplication.kt b/app/src/main/java/com/sopt/now/compose/SoptApplication.kt index aeeadab..2f48d3e 100644 --- a/app/src/main/java/com/sopt/now/compose/SoptApplication.kt +++ b/app/src/main/java/com/sopt/now/compose/SoptApplication.kt @@ -1,8 +1,6 @@ package com.sopt.now.compose import android.app.Application -import android.content.Context -import android.widget.Toast import com.sopt.now.compose.container.AppContainer import com.sopt.now.compose.container.SoptAppContainer diff --git a/app/src/main/java/com/sopt/now/compose/container/AppContainer.kt b/app/src/main/java/com/sopt/now/compose/container/AppContainer.kt new file mode 100644 index 0000000..1fd26ef --- /dev/null +++ b/app/src/main/java/com/sopt/now/compose/container/AppContainer.kt @@ -0,0 +1,13 @@ +package com.sopt.now.compose.container + +import com.sopt.now.compose.container.impl.AuthRepositoryImpl +import com.sopt.now.compose.container.impl.FollowerRepositoryImpl +import com.sopt.now.compose.container.impl.MemberRepositoryImpl +import com.sopt.now.compose.container.impl.UserRepositoryImpl + +interface AppContainer{ + val userRepository: UserRepositoryImpl + val followRepository: FollowerRepositoryImpl + val memberRepository: MemberRepositoryImpl + val authRepository: AuthRepositoryImpl +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/compose/container/SoptAppContainer.kt b/app/src/main/java/com/sopt/now/compose/container/SoptAppContainer.kt index 07fe611..00996ba 100644 --- a/app/src/main/java/com/sopt/now/compose/container/SoptAppContainer.kt +++ b/app/src/main/java/com/sopt/now/compose/container/SoptAppContainer.kt @@ -3,40 +3,35 @@ package com.sopt.now.compose.container import android.content.Context import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.sopt.now.compose.BuildConfig -import com.sopt.now.compose.container.PreferenceUserRepository.Companion.USER_ID_KEY -import com.sopt.now.compose.network.FollowService +import com.sopt.now.compose.container.impl.AuthRepositoryImpl +import com.sopt.now.compose.container.impl.FollowerRepositoryImpl +import com.sopt.now.compose.container.impl.MemberRepositoryImpl +import com.sopt.now.compose.container.impl.UserRepositoryImpl import com.sopt.now.compose.network.AuthService +import com.sopt.now.compose.network.FollowService import kotlinx.serialization.json.Json import okhttp3.Interceptor import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import retrofit2.Retrofit -import retrofit2.create -interface AppContainer{ - val userRepository: PreferenceUserRepository - val followRepository: NetworkFollowerRepository - val memberRepository: NetworkMemberRepository - val authRepository: NetworkAuthRepository -} - class SoptAppContainer(context: Context): AppContainer { - override val userRepository: PreferenceUserRepository by lazy { - PreferenceUserRepository(context.getSharedPreferences(PREFERENCE_ID, Context.MODE_PRIVATE)) + override val userRepository: UserRepositoryImpl by lazy { + UserRepositoryImpl(context.getSharedPreferences(PREFERENCE_ID, Context.MODE_PRIVATE)) } - override val followRepository: NetworkFollowerRepository by lazy { - NetworkFollowerRepository(followService = retrofitFollower.create(FollowService::class.java)) + override val followRepository: FollowerRepositoryImpl by lazy { + FollowerRepositoryImpl(followService = retrofitFollower.create(FollowService::class.java)) } - override val memberRepository: NetworkMemberRepository by lazy { - NetworkMemberRepository(authService = retrofitUser.create(AuthService::class.java)) + override val memberRepository: MemberRepositoryImpl by lazy { + MemberRepositoryImpl(authService = retrofitUser.create(AuthService::class.java)) } - override val authRepository: NetworkAuthRepository by lazy { - NetworkAuthRepository(authService = retrofitLogin.create(AuthService::class.java)) + override val authRepository: AuthRepositoryImpl by lazy { + AuthRepositoryImpl(authService = retrofitLogin.create(AuthService::class.java)) } val retrofitLogin: Retrofit by lazy { @@ -61,10 +56,7 @@ class SoptAppContainer(context: Context): AppContainer { } private val okHttpClientWithInterceptor: OkHttpClient.Builder by lazy { - val memberId = context - .getSharedPreferences(PREFERENCE_ID, Context.MODE_PRIVATE) - .getString(USER_ID_KEY, "") - .orEmpty() + val memberId = userRepository.getUserId() OkHttpClient.Builder().apply { addInterceptor(Interceptor { chain -> @@ -80,7 +72,5 @@ class SoptAppContainer(context: Context): AppContainer { companion object{ const val BASE_URL = BuildConfig.AUTH_BASE_URL const val PREFERENCE_ID = "SOPT" - - private const val TAG = "SoptAppContainer" } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/compose/container/AuthRepository.kt b/app/src/main/java/com/sopt/now/compose/container/impl/AuthRepositoryImpl.kt similarity index 62% rename from app/src/main/java/com/sopt/now/compose/container/AuthRepository.kt rename to app/src/main/java/com/sopt/now/compose/container/impl/AuthRepositoryImpl.kt index fea7063..6420171 100644 --- a/app/src/main/java/com/sopt/now/compose/container/AuthRepository.kt +++ b/app/src/main/java/com/sopt/now/compose/container/impl/AuthRepositoryImpl.kt @@ -1,21 +1,14 @@ -package com.sopt.now.compose.container +package com.sopt.now.compose.container.impl +import com.sopt.now.compose.container.repository.AuthRepository import com.sopt.now.compose.network.AuthService import com.sopt.now.compose.network.dto.RequestLoginDto import com.sopt.now.compose.network.dto.RequestSignUpDto import com.sopt.now.compose.network.dto.ResponseLoginDto import com.sopt.now.compose.network.dto.ResponseSignUpDto -import com.sopt.now.compose.ui.screens.login.LoginViewModel -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.jsonObject import retrofit2.Response -interface AuthRepository { - suspend fun postLogin(request: RequestLoginDto): Result> - suspend fun postSignUp(request: RequestSignUpDto): Result> -} - -class NetworkAuthRepository( +class AuthRepositoryImpl( private val authService: AuthService ) : AuthRepository { override suspend fun postLogin(request: RequestLoginDto): Result> = diff --git a/app/src/main/java/com/sopt/now/compose/container/FollowerRepository.kt b/app/src/main/java/com/sopt/now/compose/container/impl/FollowerRepositoryImpl.kt similarity index 60% rename from app/src/main/java/com/sopt/now/compose/container/FollowerRepository.kt rename to app/src/main/java/com/sopt/now/compose/container/impl/FollowerRepositoryImpl.kt index e5f0879..2cecddc 100644 --- a/app/src/main/java/com/sopt/now/compose/container/FollowerRepository.kt +++ b/app/src/main/java/com/sopt/now/compose/container/impl/FollowerRepositoryImpl.kt @@ -1,15 +1,11 @@ -package com.sopt.now.compose.container +package com.sopt.now.compose.container.impl -import com.sopt.now.compose.models.Follower +import com.sopt.now.compose.container.repository.FollowerRepository import com.sopt.now.compose.network.FollowService import com.sopt.now.compose.network.dto.ResponseFollowListDto import retrofit2.Response -interface FollowerRepository{ - suspend fun getFollowers(page: Int = 2): Result> -} - -class NetworkFollowerRepository( +class FollowerRepositoryImpl( private val followService: FollowService ): FollowerRepository { override suspend fun getFollowers(page: Int): Result> = runCatching { diff --git a/app/src/main/java/com/sopt/now/compose/container/MemberRepository.kt b/app/src/main/java/com/sopt/now/compose/container/impl/MemberRepositoryImpl.kt similarity index 72% rename from app/src/main/java/com/sopt/now/compose/container/MemberRepository.kt rename to app/src/main/java/com/sopt/now/compose/container/impl/MemberRepositoryImpl.kt index 50b8d2d..12bceeb 100644 --- a/app/src/main/java/com/sopt/now/compose/container/MemberRepository.kt +++ b/app/src/main/java/com/sopt/now/compose/container/impl/MemberRepositoryImpl.kt @@ -1,21 +1,13 @@ -package com.sopt.now.compose.container +package com.sopt.now.compose.container.impl +import com.sopt.now.compose.container.repository.MemberRepository import com.sopt.now.compose.models.User import com.sopt.now.compose.network.AuthService import com.sopt.now.compose.network.dto.RequestChangePasswordDto import com.sopt.now.compose.network.dto.ResponseChangePasswordDto import retrofit2.Response -private const val TAG = "AuthRepository" - -interface MemberRepository { - suspend fun getUserInfo(): Result - suspend fun patchUserPassword( - request: RequestChangePasswordDto - ): Response -} - -class NetworkMemberRepository( +class MemberRepositoryImpl( private val authService: AuthService ) : MemberRepository { override suspend fun getUserInfo(): Result = runCatching { diff --git a/app/src/main/java/com/sopt/now/compose/container/UserRepository.kt b/app/src/main/java/com/sopt/now/compose/container/impl/UserRepositoryImpl.kt similarity index 63% rename from app/src/main/java/com/sopt/now/compose/container/UserRepository.kt rename to app/src/main/java/com/sopt/now/compose/container/impl/UserRepositoryImpl.kt index 591ba61..9b80b36 100644 --- a/app/src/main/java/com/sopt/now/compose/container/UserRepository.kt +++ b/app/src/main/java/com/sopt/now/compose/container/impl/UserRepositoryImpl.kt @@ -1,23 +1,13 @@ -package com.sopt.now.compose.container +package com.sopt.now.compose.container.impl import android.content.SharedPreferences -import android.util.Log +import com.sopt.now.compose.container.repository.UserRepository import com.sopt.now.compose.models.User -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -interface UserRepository { - suspend fun getUserProfile(): User? - suspend fun setUserProfile(user: User) - - suspend fun getUserId(): String - suspend fun setUserId(userId: String) -} - -class PreferenceUserRepository( - val sharedPreferences: SharedPreferences +class UserRepositoryImpl( + private val sharedPreferences: SharedPreferences ) : UserRepository { - override suspend fun getUserProfile(): User { + override fun getUserProfile(): User { sharedPreferences.run { val id = getString(ID_KEY, "") ?: "" val pw = getString(PW_KEY, "") ?: "" @@ -27,7 +17,7 @@ class PreferenceUserRepository( } } - override suspend fun setUserProfile(user: User) { + override fun setUserProfile(user: User) { val edit = sharedPreferences.edit() edit.run { putString(ID_KEY, user.id) @@ -38,12 +28,11 @@ class PreferenceUserRepository( } } - override suspend fun getUserId(): String { + override fun getUserId(): String { return sharedPreferences.getString(USER_ID_KEY, "").orEmpty() } - override suspend fun setUserId(userId: String) { - Log.d(TAG, "userId: $userId") + override fun setUserId(userId: String) { val edit = sharedPreferences.edit() edit.putString(USER_ID_KEY, userId).apply() diff --git a/app/src/main/java/com/sopt/now/compose/container/repository/AuthRepository.kt b/app/src/main/java/com/sopt/now/compose/container/repository/AuthRepository.kt new file mode 100644 index 0000000..ad1ab28 --- /dev/null +++ b/app/src/main/java/com/sopt/now/compose/container/repository/AuthRepository.kt @@ -0,0 +1,13 @@ +package com.sopt.now.compose.container.repository + +import com.sopt.now.compose.network.dto.RequestLoginDto +import com.sopt.now.compose.network.dto.RequestSignUpDto +import com.sopt.now.compose.network.dto.ResponseLoginDto +import com.sopt.now.compose.network.dto.ResponseSignUpDto +import retrofit2.Response + +interface AuthRepository { + suspend fun postLogin(request: RequestLoginDto): Result> + suspend fun postSignUp(request: RequestSignUpDto): Result> +} + diff --git a/app/src/main/java/com/sopt/now/compose/container/repository/FollowerRepository.kt b/app/src/main/java/com/sopt/now/compose/container/repository/FollowerRepository.kt new file mode 100644 index 0000000..ccf5c68 --- /dev/null +++ b/app/src/main/java/com/sopt/now/compose/container/repository/FollowerRepository.kt @@ -0,0 +1,9 @@ +package com.sopt.now.compose.container.repository + +import com.sopt.now.compose.network.dto.ResponseFollowListDto +import retrofit2.Response + +interface FollowerRepository{ + suspend fun getFollowers(page: Int = 2): Result> +} + diff --git a/app/src/main/java/com/sopt/now/compose/container/repository/MemberRepository.kt b/app/src/main/java/com/sopt/now/compose/container/repository/MemberRepository.kt new file mode 100644 index 0000000..6d5ebd6 --- /dev/null +++ b/app/src/main/java/com/sopt/now/compose/container/repository/MemberRepository.kt @@ -0,0 +1,13 @@ +package com.sopt.now.compose.container.repository + +import com.sopt.now.compose.models.User +import com.sopt.now.compose.network.dto.RequestChangePasswordDto +import com.sopt.now.compose.network.dto.ResponseChangePasswordDto +import retrofit2.Response + +interface MemberRepository { + suspend fun getUserInfo(): Result + suspend fun patchUserPassword( + request: RequestChangePasswordDto + ): Response +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/compose/container/repository/UserRepository.kt b/app/src/main/java/com/sopt/now/compose/container/repository/UserRepository.kt new file mode 100644 index 0000000..b2dec37 --- /dev/null +++ b/app/src/main/java/com/sopt/now/compose/container/repository/UserRepository.kt @@ -0,0 +1,11 @@ +package com.sopt.now.compose.container.repository + +import com.sopt.now.compose.models.User + +interface UserRepository { + fun getUserProfile(): User? + fun setUserProfile(user: User) + fun getUserId(): String + fun setUserId(userId: String) +} + diff --git a/app/src/main/java/com/sopt/now/compose/network/AuthService.kt b/app/src/main/java/com/sopt/now/compose/network/AuthService.kt index 09496b2..a96b30c 100644 --- a/app/src/main/java/com/sopt/now/compose/network/AuthService.kt +++ b/app/src/main/java/com/sopt/now/compose/network/AuthService.kt @@ -7,7 +7,6 @@ import com.sopt.now.compose.network.dto.ResponseChangePasswordDto import com.sopt.now.compose.network.dto.ResponseLoginDto import com.sopt.now.compose.network.dto.ResponseMemberInfoDto import com.sopt.now.compose.network.dto.ResponseSignUpDto -import retrofit2.Call import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET diff --git a/app/src/main/java/com/sopt/now/compose/network/FollowService.kt b/app/src/main/java/com/sopt/now/compose/network/FollowService.kt index 97aed9d..374ceb0 100644 --- a/app/src/main/java/com/sopt/now/compose/network/FollowService.kt +++ b/app/src/main/java/com/sopt/now/compose/network/FollowService.kt @@ -1,7 +1,6 @@ package com.sopt.now.compose.network import com.sopt.now.compose.network.dto.ResponseFollowListDto -import retrofit2.Call import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Query diff --git a/app/src/main/java/com/sopt/now/compose/network/dto/ResponseFollowListDto.kt b/app/src/main/java/com/sopt/now/compose/network/dto/ResponseFollowListDto.kt index aa2b49a..d9d8967 100644 --- a/app/src/main/java/com/sopt/now/compose/network/dto/ResponseFollowListDto.kt +++ b/app/src/main/java/com/sopt/now/compose/network/dto/ResponseFollowListDto.kt @@ -9,11 +9,11 @@ data class ResponseFollowListDto( @SerialName("page") val page:Int, @SerialName("per_page") - val per_page:Int, + val perPage:Int, @SerialName("total") val total:Int, @SerialName("total_pages") - val total_pages:Int, + val totalPages:Int, @SerialName("data") val data:List, @SerialName("support") diff --git a/app/src/main/java/com/sopt/now/compose/ui/navigation/ApplicationNavigation.kt b/app/src/main/java/com/sopt/now/compose/ui/navigation/ApplicationNavigation.kt index 28b2fbc..59e1b01 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/navigation/ApplicationNavigation.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/navigation/ApplicationNavigation.kt @@ -2,15 +2,11 @@ package com.sopt.now.compose.ui.navigation import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController -import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable -import androidx.navigation.navArgument import com.sopt.now.compose.ui.screens.home.HomeScreen import com.sopt.now.compose.ui.screens.login.LoginScreen -import com.sopt.now.compose.ui.screens.login.LoginViewModel import com.sopt.now.compose.ui.screens.profile.ProfileScreen import com.sopt.now.compose.ui.screens.search.SearchScreen import com.sopt.now.compose.ui.screens.signup.SignUpScreen diff --git a/app/src/main/java/com/sopt/now/compose/ui/navigation/NavigationDestination.kt b/app/src/main/java/com/sopt/now/compose/ui/navigation/NavigationDestination.kt index d0f431e..9490881 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/navigation/NavigationDestination.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/navigation/NavigationDestination.kt @@ -1,6 +1,5 @@ package com.sopt.now.compose.ui.navigation -import androidx.annotation.StringRes import androidx.compose.ui.graphics.vector.ImageVector interface NavigationDestination { diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeScreen.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeScreen.kt index dbdd296..6c63e25 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeScreen.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeScreen.kt @@ -17,13 +17,13 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview @@ -31,6 +31,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController @@ -65,7 +66,7 @@ fun HomeScreen( Scaffold( bottomBar = { SoptBottomNavigation(navController = navController) } ) { paddingValue -> - when (val uiState = viewModel.uiState.collectAsState().value) { + when (val uiState = viewModel.uiState.collectAsStateWithLifecycle(LocalLifecycleOwner.current).value) { is HomeUiState.Success -> { HomeScreen( uiState = uiState, diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeViewModel.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeViewModel.kt index 42c2793..1c21a0d 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeViewModel.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/home/HomeViewModel.kt @@ -1,21 +1,14 @@ package com.sopt.now.compose.ui.screens.home import android.util.Log -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory -import androidx.navigation.NavHostController -import com.sopt.now.compose.MainActivity.Companion.NAVIGATE_BACK_PRESSED_KEY -import com.sopt.now.compose.MainActivity.Companion.NAVIGATE_LOGIN_KEY import com.sopt.now.compose.SoptApplication -import com.sopt.now.compose.container.FollowerRepository -import com.sopt.now.compose.container.NetworkMemberRepository -import com.sopt.now.compose.models.Follower -import com.sopt.now.compose.models.User +import com.sopt.now.compose.container.impl.MemberRepositoryImpl +import com.sopt.now.compose.container.repository.FollowerRepository import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -25,7 +18,7 @@ private const val TAG = "HomeViewModel" class HomeViewModel( private val followerRepository: FollowerRepository, - private val authRepository: NetworkMemberRepository + private val authRepository: MemberRepositoryImpl ) : ViewModel() { private val _uiState = MutableStateFlow(HomeUiState.Loading()) diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginScreen.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginScreen.kt index 54f6008..daf15af 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginScreen.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginScreen.kt @@ -2,7 +2,6 @@ package com.sopt.now.compose.ui.screens.login import android.app.Activity import android.content.Context -import android.util.Log import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -13,18 +12,19 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController @@ -41,7 +41,7 @@ fun LoginScreen( viewModel: LoginViewModel = viewModel(factory = LoginViewModel.Factory), ) { val context = LocalContext.current - val uiState by viewModel.uiState.collectAsState() + val uiState by viewModel.uiState.collectAsStateWithLifecycle(LocalLifecycleOwner.current) LaunchedEffect(uiState.message) { @@ -103,7 +103,7 @@ private fun LoginScreen( TextFieldWithTitleComposable( title = R.string.title_pw, label = R.string.login_label_pw, - textFieldText = uiState.pw, + textFieldText = uiState.password, onValueChange = onPwTextFieldChanged, keyboardType = KeyboardType.Password, imeAction = ImeAction.Done, diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginUiState.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginUiState.kt index b7a8b1c..27e9ed8 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginUiState.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginUiState.kt @@ -2,7 +2,7 @@ package com.sopt.now.compose.ui.screens.login data class LoginUiState( val id: String = "", - val pw: String = "", + val password: String = "", val isSuccess: Boolean = false, val message:String = "" ) diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginViewModel.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginViewModel.kt index 17b5151..590fd56 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginViewModel.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/login/LoginViewModel.kt @@ -7,8 +7,8 @@ import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import com.sopt.now.compose.SoptApplication -import com.sopt.now.compose.container.NetworkAuthRepository -import com.sopt.now.compose.container.PreferenceUserRepository +import com.sopt.now.compose.container.repository.AuthRepository +import com.sopt.now.compose.container.repository.UserRepository import com.sopt.now.compose.network.dto.RequestLoginDto import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -19,15 +19,15 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonObject class LoginViewModel( - private val userRepository: PreferenceUserRepository, - private val authRepository: NetworkAuthRepository + private val userRepository: UserRepository, + private val authRepository: AuthRepository ): ViewModel() { private val _uiState = MutableStateFlow(LoginUiState()) val uiState: StateFlow = _uiState.asStateFlow() fun updateUiState( id: String = _uiState.value.id, - pw: String = _uiState.value.pw, + pw: String = _uiState.value.password, isSuccess:Boolean = _uiState.value.isSuccess, message: String = _uiState.value.message @@ -35,7 +35,7 @@ class LoginViewModel( _uiState.update { currentState -> currentState.copy( id = id, - pw = pw, + password = pw, isSuccess = isSuccess, message = message ) @@ -77,10 +77,10 @@ class LoginViewModel( private fun getRequestLoginDto(): RequestLoginDto = RequestLoginDto( authenticationId = _uiState.value.id, - password = _uiState.value.pw + password = _uiState.value.password ) - private fun setUserIdInPreference(userId: String) = viewModelScope.launch { + private fun setUserIdInPreference(userId: String) { userRepository.setUserId(userId) } diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileScreen.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileScreen.kt index b41ee2f..1fafb39 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileScreen.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileScreen.kt @@ -11,20 +11,20 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import com.sopt.now.compose.MainActivity import com.sopt.now.compose.MainActivity.Companion.NAVIGATE_BACK_PRESSED_KEY import com.sopt.now.compose.R -import com.sopt.now.compose.models.User import com.sopt.now.compose.ui.SoptBottomNavigation import com.sopt.now.compose.ui.composables.ButtonComposable import com.sopt.now.compose.ui.composables.ScreenWithImage @@ -55,7 +55,7 @@ fun ProfileScreen( Scaffold( bottomBar = { SoptBottomNavigation(navController = navController) } ) { paddingValue -> - when (val uiState = viewModel.uiState.collectAsState().value) { + when (val uiState = viewModel.uiState.collectAsStateWithLifecycle(LocalLifecycleOwner.current).value) { is ProfileUiState.Success -> { ProfileScreen( uiState = uiState, diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileViewModel.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileViewModel.kt index 49af2f2..6568107 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/profile/ProfileViewModel.kt @@ -7,7 +7,7 @@ import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import com.sopt.now.compose.SoptApplication -import com.sopt.now.compose.container.NetworkMemberRepository +import com.sopt.now.compose.container.impl.MemberRepositoryImpl import com.sopt.now.compose.models.User import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch class ProfileViewModel( - private val authRepository: NetworkMemberRepository + private val authRepository: MemberRepositoryImpl ): ViewModel() { private val _uiState = MutableStateFlow(ProfileUiState.Loading) val uiState: StateFlow = _uiState.asStateFlow() diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpScreen.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpScreen.kt index 2f80ff4..d46b804 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpScreen.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpScreen.kt @@ -8,17 +8,18 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController @@ -34,7 +35,7 @@ fun SignUpScreen( ) { val context = LocalContext.current - val uiState by viewModel.uiState.collectAsState() + val uiState by viewModel.uiState.collectAsStateWithLifecycle(LocalLifecycleOwner.current) LaunchedEffect(uiState.message) { if(uiState.message.isNotEmpty()){ if(uiState.isSuccess) { diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpState.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpState.kt index 7fa9846..78c440f 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpState.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpState.kt @@ -1,7 +1,5 @@ package com.sopt.now.compose.ui.screens.signup -import com.sopt.now.compose.models.User - data class SignUpState( val isSuccess: Boolean = false, val message: String = "", diff --git a/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpViewModel.kt b/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpViewModel.kt index 80ca7d4..9da4b38 100644 --- a/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpViewModel.kt +++ b/app/src/main/java/com/sopt/now/compose/ui/screens/signup/SignUpViewModel.kt @@ -6,7 +6,7 @@ import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import com.sopt.now.compose.SoptApplication -import com.sopt.now.compose.container.NetworkAuthRepository +import com.sopt.now.compose.container.impl.AuthRepositoryImpl import com.sopt.now.compose.network.dto.RequestSignUpDto import com.sopt.now.compose.ui.screens.login.LoginViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -18,7 +18,7 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonObject class SignUpViewModel( - private val authRepository: NetworkAuthRepository + private val authRepository: AuthRepositoryImpl ): ViewModel() { private val _uiState = MutableStateFlow(SignUpState()) val uiState: StateFlow = _uiState.asStateFlow() diff --git a/app/src/test/java/com/sopt/now/compose/ExampleUnitTest.kt b/app/src/test/java/com/sopt/now/compose/ExampleUnitTest.kt index 87e6766..178278c 100644 --- a/app/src/test/java/com/sopt/now/compose/ExampleUnitTest.kt +++ b/app/src/test/java/com/sopt/now/compose/ExampleUnitTest.kt @@ -1,9 +1,8 @@ package com.sopt.now.compose +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). *