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

[feat] 자체 로그인 api 연동 #146

Merged
merged 31 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3941db4
[feat] #141 로그인 서버 통신 dto 작성
jooyyoo Sep 14, 2023
53dfaa0
[feat] #141 로그인 서버 통신 POST 서비스 추가
jooyyoo Sep 14, 2023
3e74262
[feat] #141 로그인 서버통신 datasource, repository, reposiotryImpl 추가
jooyyoo Sep 14, 2023
f3ff73c
[feat] #141 로그인 서버통신 Body 추가 수정
jooyyoo Sep 14, 2023
5d1e378
[refactor] #141 로그인 실패 바텀시트 버튼 아이디 변경
jooyyoo Sep 14, 2023
60b83e9
[refactor] #141 authViewModel 변수명 변경으로 인한 리팩토링
jooyyoo Sep 14, 2023
e2ee84b
[feat] #141 로그인 실패 바텀 시트 프래그먼트 구현
jooyyoo Sep 14, 2023
8cd03fd
[refactor] #141 닉네임 액티비티 바텀시트 래팩토링
jooyyoo Sep 14, 2023
65eeba6
[feat] #141 로컬에 isLogin 변수 추가
jooyyoo Sep 14, 2023
7964d42
[mod] #141 로그인 요청 dto 수정
jooyyoo Sep 14, 2023
6d29270
[feat] #141 자체로그인 뷰모델, 액티비티 구현
jooyyoo Sep 14, 2023
99c69e1
[chore] #141 klint 반영
jooyyoo Sep 14, 2023
1be8e84
[chore] #141 klint 반영
jooyyoo Sep 14, 2023
58d4bb4
Merge branch 'develop' into feat-login-api-connection
jooyyoo Sep 17, 2023
20b0622
[del] #141 디벨롭에서 삭제된 파일
jooyyoo Sep 17, 2023
b95f879
[mod] #141 ResponseLogin 생성으로 인한 수정사항 반영
jooyyoo Sep 17, 2023
198d7bc
Merge branch 'develop' into feat-login-api-connection
jooyyoo Sep 18, 2023
242ab76
[chore] #141 merge develop 에 빠짐
jooyyoo Sep 18, 2023
cc93fdb
[mod] #141 서버 연동 데이터Response<> 추가
jooyyoo Sep 18, 2023
376e95a
[mod] #141 로그인 실패 바텀 시트 수정
jooyyoo Sep 18, 2023
1573f91
[mod] #141 응답, 요청 @SerializedName 추가
jooyyoo Sep 18, 2023
a78f9eb
[feat] #141 로그인 액티비티, 뷰모델 서버 연동 구현
jooyyoo Sep 18, 2023
c3dc2a6
[chore] #141 merge develop
jooyyoo Sep 18, 2023
194832a
[chore] #141 klint 반영
jooyyoo Sep 18, 2023
c673d09
[chore] #141 klint 반영
jooyyoo Sep 18, 2023
13941a2
Merge branch 'develop' into feat-login-api-connection
jooyyoo Sep 18, 2023
7553fd0
[feat] #141 자체 로그인 구현 완료, 자동 로그인 구현
jooyyoo Sep 19, 2023
6054f83
[chore] #141 삭제 된 항복 복구
jooyyoo Sep 19, 2023
1cfede4
[chore] #141 로그 삭제
jooyyoo Sep 19, 2023
d346911
Merge branch 'develop' into feat-login-api-connection
jooyyoo Sep 19, 2023
d51c800
[chore] #141 klint 반영
jooyyoo Sep 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.sopt.geonppang.data.datasource.remote

import com.sopt.geonppang.data.model.request.RequestLogin
import com.sopt.geonppang.data.model.request.RequestNicknameSetting
import com.sopt.geonppang.data.model.request.RequestSignup
import com.sopt.geonppang.data.model.response.ResponseLogin
import com.sopt.geonppang.data.model.response.ResponseLogout
import com.sopt.geonppang.data.model.response.ResponseNickNameSetting
import com.sopt.geonppang.data.model.response.ResponseSignup
Expand All @@ -23,4 +25,5 @@ class AuthDataSource @Inject constructor(
suspend fun logout(): ResponseLogout = authService.logout()
suspend fun settingNickname(nickname: RequestNicknameSetting): ResponseNickNameSetting =
authService.settingNickName(nickname)
suspend fun login(requestLogin: RequestLogin): Response<ResponseLogin> = authService.login(requestLogin)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sopt.geonppang.data.model.request

import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable

@Serializable
data class RequestLogin(
@SerializedName("email")
val email: String?,
@SerializedName("password")
val password: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.sopt.geonppang.data.model.response

import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseLogin(
@SerializedName("code")
val code: String,
@SerializedName("message")
val message: String,
@SerializedName("data")
val data: String?,
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.sopt.geonppang.data.repository

import com.sopt.geonppang.data.datasource.remote.AuthDataSource
import com.sopt.geonppang.data.model.request.RequestLogin
import com.sopt.geonppang.data.model.request.RequestNicknameSetting
import com.sopt.geonppang.data.model.request.RequestSignup
import com.sopt.geonppang.data.model.response.ResponseLogin
import com.sopt.geonppang.data.model.response.ResponseLogout
import com.sopt.geonppang.data.model.response.ResponseNickNameSetting
import com.sopt.geonppang.data.model.response.ResponseSignup
Expand All @@ -26,6 +28,10 @@ class AuthRepositoryImpl @Inject constructor(
override suspend fun logout(): Result<ResponseLogout> =
runCatching { authDataSource.logout() }

override suspend fun settingNickname(nickName: RequestNicknameSetting): Result<ResponseNickNameSetting> =
runCatching { authDataSource.settingNickname(nickName) }
override suspend fun settingNickname(nickName: RequestNicknameSetting): Result<ResponseNickNameSetting> {
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
Member Author

Choose a reason for hiding this comment

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

엥 이거 왜.. 쏴리염

TODO("Not yet implemented")
}

override suspend fun login(responseLogin: RequestLogin): Result<Response<ResponseLogin>> =
Copy link
Collaborator

Choose a reason for hiding this comment

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

나중에 말하는 거 까먹을까봐
나중에 여기 네이밍 수정 한 번 플리즈

Copy link
Member Author

Choose a reason for hiding this comment

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

앗 오키염 !

runCatching { authDataSource.login(responseLogin) }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.sopt.geonppang.data.service

import com.sopt.geonppang.data.model.request.RequestLogin
import com.sopt.geonppang.data.model.request.RequestNicknameSetting
import com.sopt.geonppang.data.model.request.RequestSignup
import com.sopt.geonppang.data.model.response.ResponseLogin
import com.sopt.geonppang.data.model.response.ResponseLogout
import com.sopt.geonppang.data.model.response.ResponseNickNameSetting
import com.sopt.geonppang.data.model.response.ResponseSignup
Expand All @@ -25,6 +27,11 @@ interface AuthService {
@POST("auth/logout")
suspend fun logout(): ResponseLogout

@POST("auth/login")
suspend fun login(
@Body requestLogin: RequestLogin
): Response<ResponseLogin>

@POST("member/nickname")
suspend fun settingNickName(
@Body requestNicknameSetting: RequestNicknameSetting
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.sopt.geonppang.domain.repository

import com.sopt.geonppang.data.model.request.RequestLogin
import com.sopt.geonppang.data.model.request.RequestNicknameSetting
import com.sopt.geonppang.data.model.request.RequestSignup
import com.sopt.geonppang.data.model.response.ResponseLogin
import com.sopt.geonppang.data.model.response.ResponseLogout
import com.sopt.geonppang.data.model.response.ResponseNickNameSetting
import com.sopt.geonppang.data.model.response.ResponseSignup
Expand All @@ -17,4 +19,5 @@ interface AuthRepository {
suspend fun withdraw(): Result<ResponseWithdraw>
suspend fun logout(): Result<ResponseLogout>
suspend fun settingNickname(nickName: RequestNicknameSetting): Result<ResponseNickNameSetting>
suspend fun login(requestLogin: RequestLogin): Result<Response<ResponseLogin>>
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,59 @@
package com.sopt.geonppang.presentation.login

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.geonppang.data.datasource.local.GPDataSource
import com.sopt.geonppang.data.model.request.RequestLogin
import com.sopt.geonppang.domain.repository.AuthRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class LogInViewModel @Inject constructor() : ViewModel() {
val loginEmail = MutableLiveData("")
val loginPassword = MutableLiveData("")
class LogInViewModel @Inject constructor(
private val authRepository: AuthRepository,
private val gpDataSource: GPDataSource
) : ViewModel() {
val loginEmail = MutableStateFlow("")
val loginPassword = MutableStateFlow("")
private val _loginState = MutableStateFlow<Boolean?>(null)
val loginState get() = _loginState.asStateFlow()

fun initLogin() {
_loginState.value = null
}

fun login() {
Copy link
Member

Choose a reason for hiding this comment

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

로그 다 지워주삼염

viewModelScope.launch {
authRepository.login(RequestLogin(loginEmail.value, loginPassword.value))
.onSuccess { loginResponse ->
// Log.e("로그인 상태 확인","${loginResponse}")
val responseHeader = loginResponse.headers()
val accessToken = responseHeader[AUTHORIZATION].toString()
if (loginResponse.code() == 200) {
// Log.e("로그인 성공", "${loginResponse.code()}")
gpDataSource.accessToken = BEARER_PREFIX + accessToken
gpDataSource.isLogin = true
_loginState.value = true
}
if (loginResponse.code() == 400) {
// Log.e("로그인 실패", "${loginResponse.code()}")
_loginState.value = false
}
if (loginResponse.code() == 500) {
// Log.e("서버 오류", "${loginResponse.code()}")
}
}.onFailure { throwable ->
Timber.tag("로그인 실패 on Failure").e(throwable.message)
}
}
}

companion object {
const val AUTHORIZATION = "Authorization"
const val BEARER_PREFIX = "Bearer "
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@ package com.sopt.geonppang.presentation.login
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.sopt.geonppang.R
import com.sopt.geonppang.data.datasource.local.GPDataSource
import com.sopt.geonppang.databinding.ActivityLoginBinding
import com.sopt.geonppang.presentation.auth.SignUpActivity
import com.sopt.geonppang.presentation.home.HomeFragment
import com.sopt.geonppang.util.binding.BindingActivity
import com.sopt.geonppang.util.extension.hideKeyboard
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class LoginActivity :
Expand All @@ -19,7 +25,9 @@ class LoginActivity :
binding.viewModel = viewModel
binding.lifecycleOwner = this

autoLogin()
addListener()
collectData()
}

private fun addListener() {
Expand All @@ -34,7 +42,43 @@ class LoginActivity :
}
}

private fun collectData() {
viewModel.loginState.flowWithLifecycle(lifecycle).onEach { loginState ->
when (loginState) {
true -> {
moveToHome()
}

false -> {
showLoginFailDialog()
viewModel.initLogin()
}

else -> {}
}
}.launchIn(lifecycleScope)
}

private fun showLoginFailDialog() {
LoginFailBottomDialogFragment().show(supportFragmentManager, LOGIN_FAIL)
}

private fun moveToHome() {
startActivity(Intent(this, HomeFragment::class.java))
finish()
}

private fun moveToSignup() {
startActivity(Intent(this, SignUpActivity::class.java))
}

private fun autoLogin() {
val gpDataSource = GPDataSource(this)
if (gpDataSource.isLogin)
moveToHome()
}

companion object {
const val LOGIN_FAIL = "loginFail"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.sopt.geonppang.presentation.login

import android.os.Bundle
import android.view.View
import com.sopt.geonppang.R
import com.sopt.geonppang.databinding.DialogBottomLoginFailBinding
import com.sopt.geonppang.util.binding.BindingBottomSheetDialogFragment

class LoginFailBottomDialogFragment :
BindingBottomSheetDialogFragment<DialogBottomLoginFailBinding>(R.layout.dialog_bottom_login_fail) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = this.viewLifecycleOwner

addListeners()
}

private fun addListeners() {
binding.btnLoginFailConfirm.setOnClickListener {
dismiss()
}
}
}
7 changes: 4 additions & 3 deletions app/src/main/res/layout/activity_login.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,13 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="@dimen/spacing20"
android:layout_marginBottom="24dp"
android:backgroundTint="@{viewModel.loginPassword.length() > 0 ? @color/main_2 : @color/gray_200}"
android:enabled="@{viewModel.loginPassword.length() > 0}"
android:backgroundTint="@{viewModel.loginPassword.length > 0 ? @color/main_2 : @color/gray_200}"
android:enabled="@{viewModel.loginPassword.length > 0}"
android:onClick="@{() -> viewModel.login()}"
android:paddingVertical="18dp"
android:text="@string/login_text_phrase"
android:textAppearance="@style/TextAppearance.BodyM1"
android:textColor="@{viewModel.loginPassword.length() > 0 ? @color/white : @color/gray_400}"
android:textColor="@{viewModel.loginPassword.length > 0 ? @color/white : @color/gray_400}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_signup_nickname.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
android:layout_marginTop="16dp"
android:text="@string/tv_nickname"
android:textAppearance="@style/TextAppearance.Subhead"
android:textColor="@{!viewModel.email.empty &amp; !viewModel.isValidEmail() ? @color/error : @color/gray_400}" />
android:textColor="@{!viewModel.nickname.empty &amp; !viewModel.isValidNickname() ? @color/error : @color/gray_400}" />


<EditText
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/dialog_bottom_login_fail.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
app:layout_constraintTop_toBottomOf="@id/iv_review_writing_success" />

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_review_writing_success"
android:id="@+id/btn_login_fail_confirm"
style="@style/Widget.FullButton.Basic"
android:layout_width="0dp"
android:layout_height="wrap_content"
Expand Down
Loading