-
Notifications
You must be signed in to change notification settings - Fork 1
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/kakao_login]: 카카오 소셜 로그인, 닉네임 불러오기, 로그아웃 구현 #30
Changes from all commits
e24b7b1
f0b04fe
cb31fcc
9c0bafe
deb2ece
7c140d3
9ec42cf
e5ff432
b29e663
6991738
394008b
afdd143
9c95a29
84af8ad
46f8344
2c56cdf
c3941f6
74c9e8f
3bc8510
3b8cbf4
27d78da
c70cb1c
eb2e8f6
3e804a1
dcb394e
8f61225
cde45aa
74bf456
5b5c5b0
cbcd38d
8b196a6
f39c00e
811a6d5
acb4224
66850b4
75aa724
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 @@ | ||
/build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed | ||
plugins { | ||
hmh("feature") | ||
alias(libs.plugins.kotlin.android) | ||
} | ||
|
||
android { | ||
namespace = "com.hmh.hamyeonham.feature.login" | ||
} | ||
|
||
dependencies { | ||
implementation(projects.core.common) | ||
implementation(libs.appcompat) | ||
implementation(libs.material) | ||
implementation(libs.constraintlayout) | ||
|
||
// kakao | ||
implementation(libs.kakao.login) | ||
|
||
implementation(libs.dot.indicator) | ||
implementation(libs.coil.core) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
|
||
<application> | ||
<activity | ||
android:name=".UserInfoActivity" | ||
android:exported="false" /> | ||
<activity | ||
android:name=".LoginActivity" | ||
android:exported="false" /> | ||
</application> | ||
|
||
</manifest> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.hmh.hamyeonham.feature.login | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import androidx.activity.viewModels | ||
import androidx.appcompat.app.AppCompatActivity | ||
import com.hmh.hamyeonham.common.context.toast | ||
import com.hmh.hamyeonham.feature.login.data.DummyImage | ||
import com.hmh.hamyeonham.feature.login.databinding.ActivityLoginBinding | ||
import com.kakao.sdk.auth.model.OAuthToken | ||
import com.kakao.sdk.common.model.ClientError | ||
import com.kakao.sdk.common.model.ClientErrorCause | ||
import com.kakao.sdk.user.UserApiClient | ||
|
||
class LoginActivity : AppCompatActivity() { | ||
private lateinit var binding: ActivityLoginBinding | ||
|
||
private val loginViewModel: LoginViewModel by viewModels() | ||
private lateinit var loginViewPagerAdapter: LoginViewPagerAdapter | ||
|
||
// 삭제 예정 | ||
private val dummyImageList = listOf( | ||
DummyImage( | ||
Image = R.drawable.login_sample_rectagle_viewpager, | ||
), | ||
DummyImage( | ||
Image = R.drawable.login_sample_rectagle_viewpager, | ||
), | ||
DummyImage( | ||
Image = R.drawable.login_sample_rectagle_viewpager, | ||
), | ||
) | ||
|
||
private val callback: (OAuthToken?, Throwable?) -> Unit = { token, error -> | ||
when { | ||
error != null -> { | ||
} | ||
|
||
token != null -> { | ||
moveToUserInfoActivity() | ||
} | ||
} | ||
} | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
binding = ActivityLoginBinding.inflate(layoutInflater) | ||
super.onCreate(savedInstanceState) | ||
setContentView(binding.root) | ||
|
||
binding.btnLogin.setOnClickListener { | ||
loginWithKakaoApp() | ||
} | ||
setLoginViewPager() | ||
} | ||
|
||
private fun setLoginViewPager() { | ||
loginViewPagerAdapter = LoginViewPagerAdapter(dummyImageList) | ||
binding.run { | ||
vpLogin.adapter = loginViewPagerAdapter | ||
indicatorLoginDots.attachTo(binding.vpLogin) | ||
} | ||
} | ||
|
||
private fun loginWithKakaoApp() { | ||
if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) { | ||
UserApiClient.instance.loginWithKakaoTalk(this) { token, error -> | ||
if (error != null) { | ||
toast("카카오 로그인 실패") | ||
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) { | ||
toast("다시 로그인 해주세요.") | ||
return@loginWithKakaoTalk | ||
} | ||
loginWithKakaoAccount() | ||
} else if (token != null) { | ||
toast("카카오 로그인 성공") | ||
moveToUserInfoActivity() | ||
} | ||
} | ||
} else { | ||
loginWithKakaoAccount() | ||
} | ||
} | ||
|
||
private fun loginWithKakaoAccount() { | ||
UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) | ||
} | ||
|
||
private fun moveToUserInfoActivity() { | ||
startActivity(Intent(this, UserInfoActivity::class.java)) | ||
finish() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.hmh.hamyeonham.feature.login | ||
|
||
import androidx.lifecycle.LiveData | ||
import androidx.lifecycle.MutableLiveData | ||
import androidx.lifecycle.ViewModel | ||
|
||
class LoginViewModel : ViewModel(){ | ||
|
||
private val _kakaoLoginResult = MutableLiveData<Boolean>() | ||
val kakaoLoginResult: LiveData<Boolean> get() = _kakaoLoginResult | ||
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. 굿!@!@
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. 요 값이 왜 있는지 모르겠네욥?! 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. 뷰모델 분리하기 위해 세팅만 해두고 아직 코드가 완성되지 않아 올리지 못했습니다 ㅎㅎ.. kakaoLoginResult 라이브 데이터의 결과에 따라 로그인 액티비티에서 분기처리 진행할 예정입니다! |
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.hmh.hamyeonham.feature.login | ||
|
||
import android.view.LayoutInflater | ||
import android.view.ViewGroup | ||
import androidx.recyclerview.widget.RecyclerView | ||
import coil.load | ||
import com.hmh.hamyeonham.feature.login.data.DummyImage | ||
import com.hmh.hamyeonham.feature.login.databinding.ItemLoginViewPagerBinding | ||
|
||
class LoginViewPagerAdapter(private val imageList: List<DummyImage>) : | ||
RecyclerView.Adapter<LoginViewPagerAdapter.PagerViewHolder>() { | ||
|
||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagerViewHolder { | ||
val view = LayoutInflater.from(parent.context) | ||
.inflate(R.layout.item_login_view_pager, parent, false) | ||
return PagerViewHolder(ItemLoginViewPagerBinding.bind(view)) | ||
} | ||
|
||
class PagerViewHolder(private val binding: ItemLoginViewPagerBinding) : | ||
RecyclerView.ViewHolder(binding.root) { | ||
|
||
fun onBindView(imageInfo: DummyImage) { | ||
binding.run { | ||
ivLoginViewPagerItem.load(imageInfo.Image) { | ||
placeholder(R.drawable.login_sample_rectagle_viewpager) | ||
error(R.drawable.login_sample_rectagle_viewpager) | ||
} | ||
} | ||
} | ||
} | ||
|
||
override fun getItemCount(): Int = imageList.size | ||
|
||
override fun onBindViewHolder(holder: PagerViewHolder, position: Int) { | ||
val exploreImage = imageList[position] | ||
holder.onBindView(exploreImage) | ||
} | ||
} | ||
Comment on lines
+10
to
+38
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. 요거 리스트 어댑터로 바꿔보시면 좋을 것 같습니다. diffUtil은 ItemDiffCallback 을 사용해주세요~!! 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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
넵! 지금 뷰모델 분리하면서 조금 더 세분화 하고 있고, 예외의 경우도 공식문서에서는 유저가 임의로 로그인을 이탈하거나 취소하는 경우만 나와있어서 그 부분만 구현했는데, 또 다른 경우도 고려해보겠습니다!