Skip to content
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주차 과제] 서버 통신 심화 #11

Merged
merged 23 commits into from
Jun 15, 2023
Merged

[6주차 과제] 서버 통신 심화 #11

merged 23 commits into from
Jun 15, 2023

Conversation

leeeha
Copy link
Member

@leeeha leeeha commented Jun 2, 2023

필수 과제

  • Reqres API 통신에서 UI Layer 사용하기 (ViewModel, LiveData)
  • 회원가입 아이디, 비밀번호 조건에 맞지 않으면 경고 띄우기

심화 과제

  • 기존에 작성된 코드를 UI Layer로 분리하기
  • 양방향 데이터바인딩으로 코드 로직 개선
  • HomeFragment, GalleryFragment 로딩 뷰 구현

도전 과제

  • Data Layer 분리 (Repository, DataSource)

실행 결과

Screen_Recording_20230604_135452_GO.SOPT.Android.mp4

리팩토링 TODO

  • LoadingDialogFragment로 로딩 뷰 구현해보기
  • UiState에 Loading 추가해서 상태 관리하기
  • LiveData map 사용해서 구현해보기 -> 데이터바인딩으로 에러 상태 표시
  • EditText에 포커스가 놓이지 않았는데 error가 표시되는 문제 해결하기
  • 정규표현식에서 아이디, 비밀번호의 최소/최대 길이 상수화 시키기

@leeeha leeeha added Essential 필수 과제 Advanced 심화 과제 labels Jun 2, 2023
@leeeha leeeha requested review from b1urrrr, sxunea, lsakee and a team June 2, 2023 16:11
@leeeha leeeha self-assigned this Jun 2, 2023
Copy link
Member

@b1urrrr b1urrrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextInputEditText 커스텀하기 좀 까다로운 걸로 알고 있는데 예쁘게 잘 구현하셨네요 😮
6주차도 과제 하시느라 고생하셨습니다 👍👍

Comment on lines 48 to 54
is Success -> {
followerAdapter?.submitList(viewModel.followerList)
if(loadingDialog.isShowing) loadingDialog.dismiss()
}
is Failure -> requireContext().showSnackbar(
binding.root,
getString(R.string.gallery_follower_list_null_msg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failure인 경우에도 LoadingDialog를 dismiss 해주는 것이 좋을 것 같습니다!

return pw.isNotBlank() && pw.length in MIN_PW_LENGTH..MAX_PW_LENGTH
// 영문, 숫자, 특수문자를 적어도 하나씩 포함하는 6~12자리 문자열
// 허용되는 특수 문자: !, @, #, $, %, ^, +, -, =
val pwRegex = """^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^+\-=])[A-Za-z\d!@#$%^+\-=]{6,12}$"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
val pwRegex = """^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^+\-=])[A-Za-z\d!@#$%^+\-=]{6,12}$"""
val pwRegex = """^(?=.*[A-Za-z])(?=.*\d)(?=.*[!@#$%^+\-=])[A-Za-z\d!@#$%^+\-=]{MIN_PW_LENGTH,MAX_PWD_LENGTH}$"""

정규식에 상수를 사용하는 것이 보일러플레이트를 줄일 수 있을 것 같습니다!

Comment on lines 56 to 65
fun isNotBlankName(): Boolean {
return name.isNotBlank()
}

fun isNotBlankHobby(): Boolean {
return hobby.isNotBlank()
}

fun isValidInput(): Boolean {
return isValidId() && isValidPw() && isNotBlankName() && isNotBlankHobby()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fun isNotBlankName(): Boolean {
return name.isNotBlank()
}
fun isNotBlankHobby(): Boolean {
return hobby.isNotBlank()
}
fun isValidInput(): Boolean {
return isValidId() && isValidPw() && isNotBlankName() && isNotBlankHobby()
fun isNotBlankName() = name.isNotBlank()
fun isNotBlankHobby() = hobby.isNotBlank()
fun isValidInput() = isValidId() && isValidPw() && isNotBlankName() && isNotBlankHobby()

single expression 함수로 구현하면 조금 더 깔끔할 것 같습니다!

Comment on lines 30 to 58
binding.etId.addTextChangedListener {
if (!viewModel.isValidId()) {
binding.tilId.error = getString(R.string.sign_up_id_helper_text)
deactivateSignUpButton()
} else {
binding.tilId.error = null
if (viewModel.isValidInput()) activateSignUpButton()
}
}

binding.etPw.addTextChangedListener {
if (!viewModel.isValidPw()) {
binding.tilPw.error = getString(R.string.sign_up_pw_helper_text)
deactivateSignUpButton()
} else {
binding.tilPw.error = null
if (viewModel.isValidInput()) activateSignUpButton()
}
}

binding.etName.addTextChangedListener {
if (viewModel.isNotBlankName()) {
binding.tilName.error = null
if (viewModel.isValidInput()) activateSignUpButton()
} else {
binding.tilName.error = getString(R.string.sign_up_required_input_err)
deactivateSignUpButton()
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextChangedListener를 설정할 때 유사한 로직이 반복되고 있는데, InputEditText와 Boolean 타입의 조건을 인자로 받는 함수를 만들어 사용할 수도 있을 것 같습니다!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한개로 합칠수 있을거 같습니다

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 71 to 77
private fun activateSignUpButton() {
binding.btnSignUp.isEnabled = true
}

private fun deactivateSignUpButton() {
binding.btnSignUp.isEnabled = false
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 데이터바인딩이나 바인딩 어댑터를 활용하여 처리하면 코드를 좀 줄일 수 있을 것 같습니다!

Copy link

@lsakee lsakee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하은이 코드 너무 좋네~! 배워갑니다 !

Comment on lines 30 to 58
binding.etId.addTextChangedListener {
if (!viewModel.isValidId()) {
binding.tilId.error = getString(R.string.sign_up_id_helper_text)
deactivateSignUpButton()
} else {
binding.tilId.error = null
if (viewModel.isValidInput()) activateSignUpButton()
}
}

binding.etPw.addTextChangedListener {
if (!viewModel.isValidPw()) {
binding.tilPw.error = getString(R.string.sign_up_pw_helper_text)
deactivateSignUpButton()
} else {
binding.tilPw.error = null
if (viewModel.isValidInput()) activateSignUpButton()
}
}

binding.etName.addTextChangedListener {
if (viewModel.isNotBlankName()) {
binding.tilName.error = null
if (viewModel.isValidInput()) activateSignUpButton()
} else {
binding.tilName.error = getString(R.string.sign_up_required_input_err)
deactivateSignUpButton()
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한개로 합칠수 있을거 같습니다

@leeeha leeeha requested a review from b1urrrr June 14, 2023 08:02
Copy link
Member

@b1urrrr b1urrrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💚
앱잼 화이팅~

@leeeha leeeha merged commit d376ed2 into develop Jun 15, 2023
@leeeha leeeha linked an issue Jun 15, 2023 that may be closed by this pull request
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Advanced 심화 과제 Essential 필수 과제
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[6주차 과제] 서버 통신 심화
3 participants