Skip to content

Commit

Permalink
[Refactor] 뷰모델 UI state 관리 수정 (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
arinming committed May 23, 2024
1 parent 72ce0d5 commit ec5b22d
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 51 deletions.
4 changes: 0 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp'
implementation 'com.squareup.okhttp3:logging-interceptor'

// Glide
implementation 'com.github.bumptech.glide:glide:4.13.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0'

// Coil
implementation 'io.coil-kt:coil-compose:2.6.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ data class ResponseInfoDto(
@SerialName("message")
val message: String,
@SerialName("data")
val data: UserInfo,
val data: UserInfoDto,
)

@Serializable
data class UserInfo(
data class UserInfoDto(
@SerialName("authenticationId")
val authenticationId: String,
@SerialName("nickname")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ data class ResponseUserDto(
@SerialName("per_page") val perPage: Int,
val total: Int,
@SerialName("total_pages") val totalPages: Int,
val data: List<UserData>,
val support: Support,
val data: List<UserDataDto>,
val support: SupportDto,
)

@Serializable
data class UserData(
data class UserDataDto(
val id: Int,
val email: String,
@SerialName("first_name") val firstName: String,
Expand All @@ -23,7 +23,7 @@ data class UserData(
)

@Serializable
data class Support(
data class SupportDto(
val url: String,
val text: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.create


object ApiFactory {
Expand All @@ -32,11 +33,11 @@ object ApiFactory {
.build()
}

inline fun <reified T> createBase(): T = baseRetrofit.create(T::class.java)
inline fun <reified T> createFollower(): T = followerRetrofit.create(T::class.java)
inline fun <reified T> createBaseRetrofit(): T = baseRetrofit.create()
inline fun <reified T> createFollowerRetrofit(): T = followerRetrofit.create()
}

object ServicePool {
val authService = ApiFactory.createBase<AuthService>()
val followerService = ApiFactory.createFollower<FollowerService>()
val authService = ApiFactory.createBaseRetrofit<AuthService>()
val followerService = ApiFactory.createFollowerRetrofit<FollowerService>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.util.Log
import androidx.lifecycle.ViewModel
import com.sopt.now.compose.data.model.Profile
import com.sopt.now.compose.data.model.ResponseUserDto
import com.sopt.now.compose.data.model.UserData
import com.sopt.now.compose.data.model.UserDataDto
import com.sopt.now.compose.data.module.ServicePool
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -15,7 +15,7 @@ import retrofit2.Response
class HomeViewModel : ViewModel() {
private val followerService by lazy { ServicePool.followerService }

private val _followerState = MutableStateFlow<List<UserData>>(emptyList())
private val _followerState = MutableStateFlow<List<UserDataDto>>(emptyList())
val followerState = _followerState.asStateFlow()

val friendList = mutableListOf<Profile>()
Expand Down Expand Up @@ -45,7 +45,7 @@ class HomeViewModel : ViewModel() {
})
}

fun mapFollowersToFriendList(followers: List<UserData>) {
fun mapFollowersToFriendList(followers: List<UserDataDto>) {
for (follower in followers) {
friendList.add(
Profile(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.sopt.now.compose.ui.myPage

import android.util.Log
import androidx.lifecycle.ViewModel
import com.sopt.now.compose.data.model.ResponseInfoDto
import com.sopt.now.compose.data.model.UserInfo
import com.sopt.now.compose.data.model.UserInfoDto
import com.sopt.now.compose.data.module.ServicePool
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -20,7 +19,7 @@ class MyPageViewModel : ViewModel() {
ResponseInfoDto(
code = 0,
message = "",
data = UserInfo(authenticationId = "", nickname = "", phone = "")
data = UserInfoDto(authenticationId = "", nickname = "", phone = "")
)
)
val infoState = _infoState.asStateFlow()
Expand All @@ -46,7 +45,13 @@ class MyPageViewModel : ViewModel() {
}

override fun onFailure(call: Call<ResponseInfoDto>, t: Throwable) {
Log.e("MyPageError", "${t.message}")
_infoState.update {
ResponseInfoDto(
code = -1,
message = "${t.message}",
data = UserInfoDto(authenticationId = "", nickname = "", phone = "")
)
}
}
})
}
Expand Down
31 changes: 17 additions & 14 deletions app/src/main/java/com/sopt/now/compose/ui/signIn/SignInScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.compose.runtime.collectAsState
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.platform.LocalContext
Expand All @@ -35,17 +34,17 @@ fun SignInScreen(
signInViewModel: SignInViewModel = viewModel(),
) {
val context = LocalContext.current
val signUpState by signInViewModel.signInState.collectAsState()
val signInState by signInViewModel.signInState.collectAsState()

var id by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
val id by signInViewModel.id.collectAsState()
val password by signInViewModel.password.collectAsState()

LaunchedEffect(signUpState) {
if (signUpState.isSuccess) {
Toast.makeText(context, signUpState.message, Toast.LENGTH_SHORT).show()
onNavigateToHome.navigate("main")
} else if (signUpState.message.isNotBlank()) {
Toast.makeText(context, signUpState.message, Toast.LENGTH_SHORT).show()
LaunchedEffect(signInState) {
if (signInState.isSuccess) {
Toast.makeText(context, signInState.message, Toast.LENGTH_SHORT).show()
onNavigateToHome.navigate(context.getString(R.string.route_main))
} else if (signInState.message.isNotBlank()) {
Toast.makeText(context, signInState.message, Toast.LENGTH_SHORT).show()
}
}

Expand All @@ -68,10 +67,14 @@ fun SignInScreen(
)
Column {
SoptInputTextField(
text = R.string.label_id, value = id, onValueChange = { id = it }
text = R.string.label_id,
value = id,
onValueChange = { signInViewModel.updateId(it) }
)
SoptPasswordTextField(
text = R.string.label_pw, value = password, onValueChange = { password = it }
text = R.string.label_pw,
value = password,
onValueChange = { signInViewModel.updatePassword(it) }
)
}

Expand All @@ -89,7 +92,7 @@ fun SignInScreen(
} else {
Toast.makeText(
context,
"로그인 실패",
R.string.sign_up_fail,
Toast.LENGTH_SHORT
).show()
}
Expand All @@ -103,4 +106,4 @@ fun SignInScreen(
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,27 @@ import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response


class SignInViewModel : ViewModel() {
private val authService by lazy { ServicePool.authService }

private val _signInState = MutableStateFlow(SignInState(isSuccess = false, message = ""))
val signInState = _signInState.asStateFlow()

private val _id = MutableStateFlow("")
val id = _id.asStateFlow()

private val _password = MutableStateFlow("")
val password = _password.asStateFlow()

fun updateId(newId: String) {
_id.value = newId
}

fun updatePassword(newPassword: String) {
_password.value = newPassword
}


fun signIn(request: RequestSignInDto) {
authService.signIn(request).enqueue(
object : Callback<ResponseSignInDto> {
Expand Down Expand Up @@ -52,4 +66,4 @@ class SignInViewModel : ViewModel() {
}
)
}
}
}
27 changes: 13 additions & 14 deletions app/src/main/java/com/sopt/now/compose/ui/signUp/SignUpScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand All @@ -44,15 +43,15 @@ fun SignUpScreen(
val context = LocalContext.current
val signUpState by signUpViewModel.signUpState.collectAsState()

var id by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var nickname by remember { mutableStateOf("") }
var phone by remember { mutableStateOf("") }
val id by signUpViewModel.id.collectAsState()
val password by signUpViewModel.password.collectAsState()
val nickname by signUpViewModel.nickname.collectAsState()
val phoneNumber by signUpViewModel.phoneNumber.collectAsState()

LaunchedEffect(signUpState) {
if (signUpState.isSuccess) {
Toast.makeText(context, signUpState.message, Toast.LENGTH_SHORT).show()
onNavigateToSignIn.navigate("sign_in")
onNavigateToSignIn.navigate(context.getString(R.string.route_sign_in))
} else if (signUpState.message.isNotBlank()) {
Toast.makeText(context, signUpState.message, Toast.LENGTH_SHORT).show()
}
Expand All @@ -73,11 +72,11 @@ fun SignUpScreen(
}
}

val isSignUpButtonEnabled by remember(id, password, nickname, phone) {
val isSignUpButtonEnabled by remember(id, password, nickname, phoneNumber) {
mutableStateOf(
id.length in 6..10 && password.length in 8..12 && nickname.isNotEmpty() && !nickname.contains(
" "
) && phone.matches(Regex("^010-\\d{4}-\\d{4}\$"))
) && phoneNumber.matches(Regex("^010-\\d{4}-\\d{4}\$"))
)
}

Expand All @@ -92,19 +91,19 @@ fun SignUpScreen(
SoptInputTextField(
text = R.string.hint_id,
value = id,
onValueChange = { id = it })
onValueChange = { signUpViewModel.updateId(it) })
SoptPasswordTextField(
text = R.string.hint_pw,
value = password,
onValueChange = { password = it })
onValueChange = { signUpViewModel.updatePassword(it) })
SoptInputTextField(
text = R.string.hint_nickname,
value = nickname,
onValueChange = { nickname = it })
onValueChange = { signUpViewModel.updateNickname(it) })
SoptInputTextField(
text = R.string.hint_phone,
value = phone,
onValueChange = { phone = it })
value = phoneNumber,
onValueChange = { signUpViewModel.updatePhoneNumber(it) })
}
}
SoptOutlinedButton(text = R.string.btn_sign_up, onClick = {
Expand All @@ -114,7 +113,7 @@ fun SignUpScreen(
authenticationId = id,
password = password,
nickname = nickname,
phone = phone
phone = phoneNumber
)
)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,35 @@ class SignUpViewModel : ViewModel() {
private val _signUpState = MutableStateFlow(SignUpState(isSuccess = false, message = ""))
val signUpState = _signUpState.asStateFlow()

private val _id = MutableStateFlow("")
val id = _id.asStateFlow()

private val _password = MutableStateFlow("")
val password = _password.asStateFlow()

private val _nickname = MutableStateFlow("")
val nickname = _nickname.asStateFlow()

private val _phoneNumber = MutableStateFlow("")
val phoneNumber = _phoneNumber.asStateFlow()

fun updateId(id: String) {
_id.value = id
}

fun updatePassword(password: String) {
_password.value = password
}

fun updateNickname(nickname: String) {
_nickname.value = nickname
}

fun updatePhoneNumber(phoneNumber: String) {
_phoneNumber.value = phoneNumber
}


fun signUp(request: RequestSignUpDto) {
authService.signUp(request).enqueue(
object : Callback<ResponseSignUpDto> {
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<string name="label_phone">전화번호</string>
<string name="btn_sign_in">로그인</string>
<string name="btn_sign_up">회원가입</string>
<string name="sign_up_fail">로그인 실패</string>

<!-- SignUpScreen-->
<string name="sign_up_title">Sign Up</string>
Expand All @@ -22,4 +23,9 @@
<string name="screen_search">검색</string>
<string name="screen_my_page">마이페이지</string>

<!-- Navigation-->
<string name="route_main">main</string>
<string name="route_sign_in">sign_in</string>
<string name="route_sign_up">sign_up</string>

</resources>

0 comments on commit ec5b22d

Please sign in to comment.