Skip to content

Commit

Permalink
[Nunu/#43] feat: 9구차 구현 (#44)
Browse files Browse the repository at this point in the history
* [nunu/#43] feat: 로그인/회원가입 api 연결 구현

- Retrofit 이용
- jwt int -> string 변경

* [nunu/#43] feat: LookFragment 구현

- LookFragment의 차트 API RecyclerView에 연동하기

* [nunu/#43] feat: SplashActivity 자동로그인 구현

- jwt Header에 담기 (Retrofit 공식문서 참고)
- 성공 시 MainActivity 이동
- 실패 시 LoginActivity 이동

* [nunu/#43] feat: HomeFragment API 연동

- RetrofitInstance 추가
- AlbumApi, Album Response, AlbumService 구현
- HomeFragment 연결
  • Loading branch information
Ssamssamukja authored Jun 24, 2024
1 parent fd4ed78 commit 75287d1
Show file tree
Hide file tree
Showing 28 changed files with 623 additions and 23 deletions.
8 changes: 8 additions & 0 deletions UMC_6th/.idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions UMC_6th/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,17 @@ dependencies {
implementation("androidx.room:room-ktx:2.6.1")
implementation("androidx.room:room-runtime:2.6.1")
kapt("androidx.room:room-compiler:2.6.1")

//Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.retrofit2:adapter-rxjava2:2.9.0")

//okHttp
implementation("com.squareup.okhttp3:okhttp:4.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")

//Glide
implementation("com.github.bumptech.glide:glide:4.11.0")
annotationProcessor("com.github.bumptech.glide:compiler:4.11.0")
}
1 change: 1 addition & 0 deletions UMC_6th/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
android:label="FLO"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/Theme.UMC_6th"
tools:targetApi="31">
<service
Expand Down
9 changes: 9 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/AlbumApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.umc_6th

import retrofit2.Call
import retrofit2.http.GET

interface AlbumApi {
@GET("/albums")
fun getAlbums(): Call<AlbumResponse>
}
20 changes: 20 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/AlbumResponse.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.umc_6th

import com.google.gson.annotations.SerializedName

data class AlbumResponse( @SerializedName("isSuccess") val isSuccess: Boolean,
@SerializedName("code") val code: Int,
@SerializedName("message") val message: String,
@SerializedName("result") val result: TodayAlbumResult)


data class TodayAlbumResult(
@SerializedName("albums") val albums: List<TodayAlbum>
)

data class TodayAlbum(
@SerializedName("albumIdx") val albumIdx: Int,
@SerializedName("singer") val singer: String,
@SerializedName("title") val title:String,
@SerializedName("coverImgUrl") val coverImgUrl : String
)
40 changes: 40 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/AlbumService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.example.umc_6th

import android.util.Log
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class AlbumService {
private lateinit var homeAlbumView: HomeAlbumView

fun setHomeAlbumView(homeAlbumView: HomeAlbumView) {
this.homeAlbumView = homeAlbumView
}

fun getAlbum() {
homeAlbumView.onGetAlbumLoading()

RetrofitInstance.albumApi.getAlbums().enqueue(object : Callback<AlbumResponse> {
override fun onResponse(call: Call<AlbumResponse>, response: Response<AlbumResponse>) {
if (response.isSuccessful && response.code() == 200) {
val albumResponse: AlbumResponse = response.body()!!

Log.d("ALBUM-RESPONSE", albumResponse.toString())

when (val code = albumResponse.code) {
1000 -> {
homeAlbumView.onGetAlbumSuccess(code, albumResponse.result!!)
}

else -> homeAlbumView.onGetAlbumFailure(code, albumResponse.message)
}
}
}

override fun onFailure(call: Call<AlbumResponse>, t: Throwable) {
homeAlbumView.onGetAlbumFailure(400, "네트워크 오류가 발생했습니다.")
}
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.umc_6th

class ApiRepository {
companion object {
const val BASE_URL = "https://edu-api-test.softsquared.com"
}
}
13 changes: 13 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.umc_6th

import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

interface AuthApi {
@POST("/users")
fun signUp(@Body user : User) : Call<BaseResponse>

@POST("/users/login")
fun login(@Body user : User) : Call<BaseResponse>
}
52 changes: 52 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/AuthService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.example.umc_6th

import android.util.Log
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class AuthService {
private lateinit var signUpView: SignUpView
private lateinit var loginView: LoginView

fun setSignUpView(signUpView: SignUpView) {
this.signUpView = signUpView
}

fun setLoginView(loginView: LoginView) {
this.loginView = loginView
}

fun signUp(user : User) {
RetrofitInstance.authApi.signUp(user).enqueue(object: Callback<BaseResponse> {
override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {
Log.d("SignUp-Success", response.toString())
val response : BaseResponse = response.body()!!
when(response.code) {
1000 -> signUpView.onSignUpSuccess()
else -> signUpView.onSignUpFailure(response.message)
}
}
override fun onFailure(call: Call<BaseResponse>, t: Throwable) {
Log.d("SignUp-Failure", t.message.toString())
}
})
Log.d("SignUpActivity", "All Finished")
}
fun login(user : User) {
RetrofitInstance.authApi.login(user).enqueue(object: Callback<BaseResponse> {
override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {
Log.d("Login-Success", response.toString())
val response : BaseResponse = response.body()!!
when(val code = response.code) {
1000 -> loginView.onLoginSuccess(code, response.result!!)
else -> loginView.onLoginFailure(response.message)
}
}
override fun onFailure(call: Call<BaseResponse>, t: Throwable) {
Log.d("Login-Failure", t.message.toString())
}
})
Log.d("LoginActivity", "All Finished")
}
}
15 changes: 15 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.umc_6th

import com.google.gson.annotations.SerializedName

data class BaseResponse(
@SerializedName("isSuccess") val isSuccess : Boolean,
@SerializedName("code") val code : Int,
@SerializedName("message") val message : String,
@SerializedName("result") val result : Result?
)

data class Result (
@SerializedName("userIdx") var userIdx : Int,
@SerializedName("jwt") var jwt : String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.umc_6th

interface HomeAlbumView {
fun onGetAlbumLoading()
fun onGetAlbumSuccess(code: Int, result: TodayAlbumResult)
fun onGetAlbumFailure(code: Int, message: String)
}
38 changes: 36 additions & 2 deletions UMC_6th/app/src/main/java/com/example/umc_6th/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,22 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.umc_6th.adapter.AlbumRecyclerAdapter
import com.example.umc_6th.adapter.SongRecyclerViewAdapter
import com.google.gson.Gson


class HomeFragment : Fragment() {
// 여기에 Fragment의 구현 내용을 작성합니다.
class HomeFragment : Fragment()
//, HomeAlbumView
{
private lateinit var viewModel: SharedViewModel
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private lateinit var handler: Handler
private lateinit var runnable: Runnable
private var albumDatas = ArrayList<Album>()
private lateinit var songDB: SongDatabase
// 앨범 api 연결
private lateinit var todayAlbumAdapter: AlbumRecyclerAdapter


override fun onCreateView(
Expand Down Expand Up @@ -188,4 +192,34 @@ class HomeFragment : Fragment() {
class FragmentHomeBanner : Fragment(R.layout.fragment_home_banner1) {
// 필요한 경우 여기에 로직 추가
}

/*
// album api에서 가져오기
private fun loadAlbums() {
val albumService = AlbumService()
albumService.setHomeAlbumView(this)
albumService.getAlbum()
}
override fun onGetAlbumLoading() {
binding.lookLoadingPb.visibility = View.VISIBLE
}
private fun initRecyclerView(result: TodayAlbumResult) {
todayAlbumAdapter = AlbumRecyclerAdapter(requireContext(), result)
binding.homeTodayMusicAlbum.adapter = todayAlbumAdapter
}
override fun onGetAlbumSuccess(code: Int, result: TodayAlbumResult) {
binding.lookLoadingPb.visibility = View.GONE
initRecyclerView(result)
}
override fun onGetAlbumFailure(code: Int, message: String) {
binding.lookLoadingPb.visibility = View.GONE
Log.d("HOME-FRAG/ALBUM-RESPONSE", message)
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ class LockerFragment : Fragment() {
}

// 로그인 또는 로그아웃 기능
private fun getJwt() : Int {
private fun getJwt() : String? {
val spf = requireActivity().getSharedPreferences("auth", AppCompatActivity.MODE_PRIVATE)
return spf!!.getInt("jwt", 0)
return spf!!.getString("jwt", "")
}

private fun initViews() {
val jwt: Int = getJwt()
if (jwt == 0) {
val jwt: String = getJwt().toString()
if (jwt == "") {
binding.txLogin.text="로그인"
binding.txLogin.setOnClickListener{
startActivity(Intent(requireActivity(), LoginActivity::class.java))
Expand Down
25 changes: 21 additions & 4 deletions UMC_6th/app/src/main/java/com/example/umc_6th/LoginActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.umc_6th.databinding.ActivityLoginBinding

class LoginActivity : AppCompatActivity() {
class LoginActivity : AppCompatActivity(), LoginView {

private var _binding : ActivityLoginBinding? = null
private val binding get() = _binding!!
Expand Down Expand Up @@ -44,30 +44,47 @@ class LoginActivity : AppCompatActivity() {
val pwd : String = binding.loginPasswordEt.text.toString()

val songDB = SongDatabase.getInstance(this)!!
/*
val user = songDB.userDao().getUser(email, pwd)
if (user != null) {
Log.d("LoginActivity", user.id.toString())
saveJwt(user.id)
saveJwt(user.id.toString())
startMainActivity()
} else {
Toast.makeText(this, "회원 정보가 존재하지 않습니다", Toast.LENGTH_SHORT).show()
}
*/

val authService = AuthService()
authService.setLoginView(this)

authService.login(User(email, pwd, ""))
}

private fun startMainActivity() {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}

private fun saveJwt(jwt: Int) {
private fun saveJwt(jwt: String) {
val spf = getSharedPreferences("auth" , MODE_PRIVATE)
val editor = spf.edit()

editor.putInt("jwt", jwt)
editor.putString("jwt", jwt)
editor.apply()
}

override fun onLoginSuccess(code : Int, result : Result) {
saveJwt(result.jwt)
startMainActivity()
}

override fun onLoginFailure(message : String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

override fun onDestroy() {
super.onDestroy()
_binding = null
Expand Down
6 changes: 6 additions & 0 deletions UMC_6th/app/src/main/java/com/example/umc_6th/LoginView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.example.umc_6th

interface LoginView {
fun onLoginSuccess(code : Int, result : Result)
fun onLoginFailure(message : String)
}
Loading

0 comments on commit 75287d1

Please sign in to comment.