-
Notifications
You must be signed in to change notification settings - Fork 0
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
6주차 세미나 과제 #12
6주차 세미나 과제 #12
Changes from all commits
03b2822
f0fa35b
161d65a
6364022
304a92f
b284db2
4418e7e
5b23818
b03dbb5
f9065cd
4c787bc
c7c5c39
9042663
b220c8e
1f249bc
cb8687d
e65a689
c80307e
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,20 @@ | ||
package org.android.go.sopt.presentation.dialog | ||
|
||
import android.os.Bundle | ||
import android.view.View | ||
import org.android.go.sopt.R | ||
import org.android.go.sopt.databinding.FragmentLoadingDialogBinding | ||
import org.android.go.sopt.util.binding.BindingDialogFragment | ||
|
||
class LoadingDialogFragment : | ||
BindingDialogFragment<FragmentLoadingDialogBinding>(R.layout.fragment_loading_dialog) { | ||
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. 오호 다이얼로그 프래그먼트도 이렇게 base를 만들어서 사용할 수 있네요! 리팩토링 때 반영하겠습니다 :) |
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
super.onViewCreated(view, savedInstanceState) | ||
|
||
initDialogCancelable() | ||
} | ||
|
||
private fun initDialogCancelable() { | ||
dialog?.setCancelable(false) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import androidx.activity.viewModels | |
import dagger.hilt.android.AndroidEntryPoint | ||
import org.android.go.sopt.R | ||
import org.android.go.sopt.databinding.ActivityLoginBinding | ||
import org.android.go.sopt.presentation.dialog.LoadingDialogFragment | ||
import org.android.go.sopt.presentation.main.MainActivity | ||
import org.android.go.sopt.presentation.signup.SignupActivity | ||
import org.android.go.sopt.util.binding.BindingActivity | ||
|
@@ -16,12 +17,15 @@ import org.android.go.sopt.util.extension.showSnackbar | |
import org.android.go.sopt.util.extension.showToast | ||
import org.android.go.sopt.util.state.RemoteUiState.Error | ||
import org.android.go.sopt.util.state.RemoteUiState.Failure | ||
import org.android.go.sopt.util.state.RemoteUiState.Loading | ||
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도 UiState 중 하나로 분류해서 하니까 코드가 간결하네요! 구웃~~ |
||
import org.android.go.sopt.util.state.RemoteUiState.Success | ||
|
||
@AndroidEntryPoint | ||
class LoginActivity : BindingActivity<ActivityLoginBinding>(R.layout.activity_login) { | ||
private val viewModel by viewModels<LoginViewModel>() | ||
|
||
private val loadingDialog by lazy { LoadingDialogFragment() } | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
binding.vm = viewModel | ||
|
@@ -46,18 +50,41 @@ class LoginActivity : BindingActivity<ActivityLoginBinding>(R.layout.activity_lo | |
private fun setupLoginState() { | ||
viewModel.loginState.observe(this) { state -> | ||
when (state) { | ||
is Success -> navigateToMainScreen() | ||
is Failure -> showSnackbar(binding.root, getString(R.string.wrong_input_msg)) | ||
is Error -> showSnackbar(binding.root, getString(R.string.unknown_error_msg)) | ||
is Loading -> { | ||
loadingDialog.show(supportFragmentManager, TAG_LOADING_DIALOG) | ||
} | ||
|
||
is Success -> { | ||
dismissLoadingDialog() | ||
navigateToMainScreen() | ||
} | ||
|
||
is Failure -> { | ||
dismissLoadingDialog() | ||
showSnackbar(binding.root, getString(R.string.wrong_input_msg)) | ||
} | ||
|
||
is Error -> { | ||
dismissLoadingDialog() | ||
showSnackbar(binding.root, getString(R.string.unknown_error_msg)) | ||
} | ||
} | ||
} | ||
} | ||
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. 아하 로딩 다이얼로그를 따로 프래그먼트로 세워두고 적용시키는 방식이군요 !! 훔쳐갈게요 |
||
|
||
private fun dismissLoadingDialog() { | ||
if (loadingDialog.isAdded) loadingDialog.dismiss() | ||
} | ||
|
||
private fun navigateToMainScreen() { | ||
showToast(getString(R.string.login_login_success_msg)) | ||
Intent(this, MainActivity::class.java).apply { | ||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK | ||
startActivity(this) | ||
} | ||
} | ||
|
||
companion object { | ||
const val TAG_LOADING_DIALOG = "LOADING_DIALOG" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ import org.android.go.sopt.domain.repository.AuthRepository | |
import org.android.go.sopt.util.state.RemoteUiState | ||
import org.android.go.sopt.util.state.RemoteUiState.Error | ||
import org.android.go.sopt.util.state.RemoteUiState.Failure | ||
import org.android.go.sopt.util.state.RemoteUiState.Loading | ||
import org.android.go.sopt.util.state.RemoteUiState.Success | ||
import retrofit2.HttpException | ||
import timber.log.Timber | ||
|
@@ -43,19 +44,19 @@ class LoginViewModel @Inject constructor( | |
} | ||
} | ||
|
||
private fun isValidInput() = id.isNotBlank() && pwd.isNotBlank() | ||
|
||
fun login() { | ||
if (!isValidInput()) { | ||
_loginState.value = Failure(null) | ||
return | ||
} | ||
|
||
val requestPostSignInDto = RequestPostSignInDto( | ||
id = id, | ||
password = pwd, | ||
) | ||
viewModelScope.launch { | ||
_loginState.value = Loading | ||
|
||
if (!isValidInput()) { | ||
_loginState.value = Failure(CODE_INVALID_INPUT) | ||
return@launch | ||
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. 혹시 이거는 무슨 의미인지 알 수 있을까요? 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. 로그인 할 때 아이디랑 비밀번호 중 하나라도 비워져있으면 오류 메시지를 띄우도록 하는 코드입니다! |
||
} | ||
|
||
val requestPostSignInDto = RequestPostSignInDto( | ||
id = id, | ||
password = pwd, | ||
) | ||
authRepository.postSignin(requestPostSignInDto) | ||
.onSuccess { response -> | ||
authRepository.setSignedUpUser( | ||
|
@@ -82,6 +83,8 @@ class LoginViewModel @Inject constructor( | |
} | ||
} | ||
|
||
private fun isValidInput() = id.isNotBlank() && pwd.isNotBlank() | ||
|
||
companion object { | ||
const val CODE_INVALID_INPUT = 400 | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,38 +8,52 @@ import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup | |
import dagger.hilt.android.AndroidEntryPoint | ||
import org.android.go.sopt.R | ||
import org.android.go.sopt.databinding.FragmentFollowerBinding | ||
import org.android.go.sopt.presentation.dialog.LoadingDialogFragment | ||
import org.android.go.sopt.presentation.login.LoginActivity.Companion.TAG_LOADING_DIALOG | ||
import org.android.go.sopt.presentation.main.follower.FollowerAdapter.Companion.VIEW_TYPE_HEADER | ||
import org.android.go.sopt.util.binding.BindingFragment | ||
import org.android.go.sopt.util.extension.showSnackbar | ||
import org.android.go.sopt.util.state.RemoteUiState.Error | ||
import org.android.go.sopt.util.state.RemoteUiState.Failure | ||
import org.android.go.sopt.util.state.RemoteUiState.Loading | ||
import org.android.go.sopt.util.state.RemoteUiState.Success | ||
|
||
@AndroidEntryPoint | ||
class FollowerFragment : BindingFragment<FragmentFollowerBinding>(R.layout.fragment_follower) { | ||
private val viewModel by viewModels<FollowerViewModel>() | ||
|
||
private var followerAdapter: FollowerAdapter? = null | ||
private var _followerAdapter: FollowerAdapter? = null | ||
private val followerAdapter | ||
get() = requireNotNull(_followerAdapter) { getString(R.string.adapter_not_initialized_error_msg) } | ||
|
||
private var _loadingDialog: LoadingDialogFragment? = null | ||
private val loadingDialog | ||
get() = requireNotNull(_loadingDialog) { getString(R.string.dialog_not_initialized_error_msg) } | ||
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. 오 이렇게 backing properties를 사용하니까 변수에 대한 불변성과 널 안정성이 더 높아진 거 같네요! 👍 |
||
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
super.onViewCreated(view, savedInstanceState) | ||
binding.vm = viewModel | ||
|
||
initFollowerAdapter() | ||
initLoadingDialogFragment() | ||
initRecyclerViewLayoutManager() | ||
setupGetFollowerListState() | ||
} | ||
|
||
private fun initFollowerAdapter() { | ||
followerAdapter = FollowerAdapter() | ||
_followerAdapter = FollowerAdapter() | ||
binding.rvFollower.adapter = followerAdapter | ||
} | ||
|
||
private fun initLoadingDialogFragment() { | ||
_loadingDialog = LoadingDialogFragment() | ||
} | ||
|
||
private fun initRecyclerViewLayoutManager() { | ||
val layoutManager = GridLayoutManager(activity, 2) | ||
layoutManager.spanSizeLookup = object : SpanSizeLookup() { | ||
override fun getSpanSize(position: Int): Int { | ||
return when (followerAdapter?.getItemViewType(position)) { | ||
return when (followerAdapter.getItemViewType(position)) { | ||
VIEW_TYPE_HEADER -> 2 | ||
else -> 1 | ||
} | ||
|
@@ -51,16 +65,42 @@ class FollowerFragment : BindingFragment<FragmentFollowerBinding>(R.layout.fragm | |
private fun setupGetFollowerListState() { | ||
viewModel.getFollowerListState.observe(viewLifecycleOwner) { state -> | ||
when (state) { | ||
is Success -> followerAdapter?.submitList(viewModel.followerList) | ||
is Failure -> requireContext().showSnackbar(binding.root, getString(R.string.follower_get_follower_list_null_msg)) | ||
is Error -> requireContext().showSnackbar(binding.root, getString(R.string.unknown_error_msg)) | ||
is Loading -> { | ||
loadingDialog.show(parentFragmentManager, TAG_LOADING_DIALOG) | ||
} | ||
|
||
is Success -> { | ||
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. 오,,, 각 상태별로 로직을 처리하니까 가독성이 훨씬 좋네요 👍 |
||
dismissLoadingDialog() | ||
followerAdapter.submitList(viewModel.followerList) | ||
} | ||
|
||
is Failure -> { | ||
dismissLoadingDialog() | ||
requireContext().showSnackbar( | ||
binding.root, | ||
getString(R.string.follower_get_follower_list_null_msg), | ||
) | ||
} | ||
|
||
is Error -> { | ||
dismissLoadingDialog() | ||
requireContext().showSnackbar( | ||
binding.root, | ||
getString(R.string.unknown_error_msg), | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun dismissLoadingDialog() { | ||
if (loadingDialog.isAdded) loadingDialog.dismiss() | ||
} | ||
|
||
override fun onDestroyView() { | ||
super.onDestroyView() | ||
followerAdapter = null | ||
_followerAdapter = null | ||
_loadingDialog = null | ||
} | ||
|
||
companion object { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시 LoadingDialogFragment의 BindingDialogFragment를 따로 만들어둔 특별한 이유가 있는지 궁금합니당 어차피 하나의 LoadingDialogFragment로만 계속 사용하지 않나용?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로그아웃 경고 문구 구현할 때에도 BindingDialogFragment를 활용했었습니당
다른 DialogFragment가 추가되는 경우를 고려하면 유지보수에도 좋을 것 같네요!