-
Notifications
You must be signed in to change notification settings - Fork 0
[Week7] Compose 필수 과제 #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop-compose
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.sopt.now.compose.repository | ||
|
|
||
| import com.sopt.now.compose.data.model.ResponseUserDto | ||
| import com.sopt.now.compose.data.module.ServicePool | ||
| import kotlinx.coroutines.Dispatchers | ||
| import kotlinx.coroutines.withContext | ||
| import retrofit2.Response | ||
|
|
||
| class FollowerRepository { | ||
| private val followerService = ServicePool.followerService | ||
|
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| suspend fun getUserList(page: Int): Response<ResponseUserDto> { | ||
| return withContext(Dispatchers.IO) { | ||
| followerService.getUserList(page).execute() | ||
|
Comment on lines
+12
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 레트로핏 Service 에서 suspend 키워드를 붙이면 내부적으로 코루틴으로 서버 통신을 비동기 처리합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 조금 어려운 내용일 수 있는데요..! https://developer.android.com/kotlin/coroutines/coroutines-best-practices#inject-dispatchers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. withContext 와 CoroutineScope 의 차이는 뭘까요?! 🤔 이것도 추후 코루틴에 대해 자세히 학습하실 때 공부하시면 좋을 것 같습니다!
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CoroutineScope는 코루틴을 시작하고 관리하지만 withContext는 다른 Dispatcher에서 실행할 때 사용된다..정도일까용!! 코루틴 관련해서 더 깊게 공부해야 할 것 같아요 감사합니다 ㅜㅜ |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,59 +1,69 @@ | ||
| package com.sopt.now.compose.ui.home | ||
|
|
||
| import android.util.Log | ||
| import androidx.lifecycle.LiveData | ||
| import androidx.lifecycle.MutableLiveData | ||
| import androidx.lifecycle.ViewModel | ||
| import androidx.lifecycle.viewModelScope | ||
| import com.sopt.now.compose.data.model.Profile | ||
| import com.sopt.now.compose.data.model.ResponseUserDto | ||
| import com.sopt.now.compose.data.model.UserDataDto | ||
| import com.sopt.now.compose.data.module.ServicePool | ||
| import com.sopt.now.compose.repository.FollowerRepository | ||
| import kotlinx.coroutines.flow.MutableStateFlow | ||
| import kotlinx.coroutines.flow.asStateFlow | ||
| import retrofit2.Call | ||
| import retrofit2.Callback | ||
| import retrofit2.Response | ||
| import kotlinx.coroutines.launch | ||
| import java.io.IOException | ||
|
|
||
| class HomeViewModel : ViewModel() { | ||
| private val followerService by lazy { ServicePool.followerService } | ||
| private val followerRepository = FollowerRepository() | ||
|
|
||
| private val _followerState = MutableStateFlow<List<UserDataDto>>(emptyList()) | ||
| val followerState = _followerState.asStateFlow() | ||
|
|
||
| private var _eventNetworkError = MutableLiveData(false) | ||
| val eventNetworkError: LiveData<Boolean> | ||
| get() = _eventNetworkError | ||
|
|
||
|
Comment on lines
+22
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 변수는 사용하고 있지 않군요 🥲
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. StateFlow로 전체적용하려고 하다가 빠뜨린 것 같습니당..! 지우도록 하겄습니다 🫡 |
||
| private var _isNetworkErrorShown = MutableLiveData(false) | ||
|
|
||
| val friendList = mutableListOf<Profile>() | ||
|
|
||
| init { | ||
| fetchFollowerList() | ||
| } | ||
|
|
||
| private fun fetchFollowerList() { | ||
| followerService.getUserList(page = 0).enqueue(object : Callback<ResponseUserDto> { | ||
| override fun onResponse( | ||
| call: Call<ResponseUserDto>, | ||
| response: Response<ResponseUserDto>, | ||
| ) { | ||
| viewModelScope.launch { | ||
| try { | ||
| val response = followerRepository.getUserList(0) | ||
| if (response.isSuccessful) { | ||
| val data = response.body()?.data | ||
| if (data != null) { | ||
| response.body()?.data?.let { data -> | ||
| _followerState.value = data | ||
| mapFollowersToFriendList(data) | ||
| } | ||
| _eventNetworkError.value = false | ||
| _isNetworkErrorShown.value = false | ||
| } else { | ||
| _eventNetworkError.value = true | ||
| } | ||
| } catch (networkError: IOException) { | ||
| _eventNetworkError.value = true | ||
| Log.e("HomeError", "${networkError.message}") | ||
| } | ||
| } | ||
| } | ||
|
|
||
| override fun onFailure(call: Call<ResponseUserDto>, t: Throwable) { | ||
| Log.e("HomeError", "${t.message}") | ||
| } | ||
| }) | ||
| fun onNetworkErrorShown() { | ||
| _isNetworkErrorShown.value = true | ||
| } | ||
|
|
||
| fun mapFollowersToFriendList(followers: List<UserDataDto>) { | ||
| for (follower in followers) { | ||
| friendList.add( | ||
| Profile( | ||
| profileImage = follower.avatar, | ||
| name = "${follower.firstName} ${follower.lastName}", | ||
| description = follower.email | ||
| ) | ||
| private fun mapFollowersToFriendList(followers: List<UserDataDto>) { | ||
| friendList.clear() | ||
| friendList.addAll(followers.map { follower -> | ||
| Profile( | ||
| profileImage = follower.avatar, | ||
| name = "${follower.firstName} ${follower.lastName}", | ||
| description = follower.email | ||
| ) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,5 +2,6 @@ package com.sopt.now.compose.ui.signUp | |
|
|
||
| sealed class SignUpSideEffect { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UiEvent 의 네이밍을 왜 XXXSideEffect 로 명명하셨는지 궁금하군요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 추가적으로 Loading 중에 message 가 정말 필요한지 궁금합니다!
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. message는 따로 필요하지 않을 것 같아요..! 삭제하겠습니다,.! |
||
| data class Success(val message: String) : SignUpSideEffect() | ||
| data class Loading(val message: String) : SignUpSideEffect() | ||
| data class Error(val message: String) : SignUpSideEffect() | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.