From 7b016261bd007a9db452d9360002472170c9c417 Mon Sep 17 00:00:00 2001 From: BAEK0111 Date: Tue, 25 Jun 2024 00:48:43 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[simba/#47]=20feat::=20API=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UMC_6th/app/build.gradle.kts | 14 ++++++ .../java/com/example/umc_6th/ApiRepository.kt | 7 +++ .../main/java/com/example/umc_6th/AuthApi.kt | 10 +++++ .../java/com/example/umc_6th/BaseResponse.kt | 7 +++ .../com/example/umc_6th/RetrofitInstance.kt | 16 +++++++ .../com/example/umc_6th/SignUpActivity.kt | 43 ++++++++++++++----- .../src/main/java/com/example/umc_6th/User.kt | 10 ++++- 7 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/ApiRepository.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/RetrofitInstance.kt diff --git a/UMC_6th/app/build.gradle.kts b/UMC_6th/app/build.gradle.kts index 5868840..5d3b704 100644 --- a/UMC_6th/app/build.gradle.kts +++ b/UMC_6th/app/build.gradle.kts @@ -56,6 +56,20 @@ dependencies { implementation("androidx.room:room-runtime:2.6.0") kapt("androidx.room:room-compiler:2.6.0") + // Retrofit + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.retrofit2:converter-gson:2.9.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2") + 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.12.0") + annotationProcessor("com.github.bumptech.glide:compiler:4.12.0") + androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") } \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/ApiRepository.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/ApiRepository.kt new file mode 100644 index 0000000..c0748a4 --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/ApiRepository.kt @@ -0,0 +1,7 @@ +package com.example.umc_6th + +class ApiRepository { + companion object{ + const val BASE_URL = "https://edu-api-test.softsquared.com" + } +} \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt new file mode 100644 index 0000000..9d75a39 --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt @@ -0,0 +1,10 @@ +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 +} \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt new file mode 100644 index 0000000..2ce028f --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt @@ -0,0 +1,7 @@ +package com.example.umc_6th + +data class BaseResponse( + val isSuccess : Boolean, + val code : Int, + val message : String +) diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/RetrofitInstance.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/RetrofitInstance.kt new file mode 100644 index 0000000..dce8b49 --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/RetrofitInstance.kt @@ -0,0 +1,16 @@ +package com.example.umc_6th + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class RetrofitInstance { + companion object{ + private val retrofit by lazy{ + Retrofit.Builder() + .baseUrl(ApiRepository.BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + } + val authApi = retrofit.create(AuthApi::class.java) + } +} \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt index 30301db..f6b05ae 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt @@ -2,9 +2,13 @@ package com.example.umc_6th import android.os.Bundle import android.util.Log +import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.example.umc_6th.databinding.ActivitySignupBinding +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response class SignUpActivity : AppCompatActivity(){ @@ -23,27 +27,46 @@ class SignUpActivity : AppCompatActivity(){ private fun getUser() : User{ val email : String = binding.signUpIdEt.text.toString() + "@" + binding.signUpDirectInputEt.text.toString() val pwd : String = binding.signUpPasswordEt.text.toString() + val name: String = binding.signUpNameEt.text.toString() - return User(email, pwd) + return User(email, pwd, name) } - private fun signUp() { + private fun signUp() : Boolean{ if (binding.signUpIdEt.text.toString().isEmpty() || binding.signUpDirectInputEt.text.toString().isEmpty()){ Toast.makeText(this,"이메일 형식이 잘못되었습니다.",Toast.LENGTH_SHORT).show() - return + return false } if (binding.signUpPasswordEt.text.toString() != binding.signUpPasswordCheckEt.text.toString()){ Toast.makeText(this,"비밀번호가 일치하지 않습니다",Toast.LENGTH_SHORT).show() - return + return false } - val userDB = SongDatabase.getInstance(this)!! - userDB.userDao().insert(getUser()) + if(binding.signUpNameEt.text.toString().isEmpty()){ + Toast.makeText(this, "이름 형식이 잘못되었습니다.", Toast.LENGTH_SHORT).show() + return false + } + + RetrofitInstance.authApi.signUp(getUser()).enqueue(object: Callback { + override fun onResponse(call: Call, response: Response) { + Log.d("SignUp-Success", response.toString()) + val response : BaseResponse = response.body()!! + when(response.code) { + 1000 -> finish() // 성공 + 2016, 2018 -> { + binding.signUpEmailErrorTv.visibility = View.VISIBLE + binding.signUpEmailErrorTv.text = response.message + } + } + + } - val user = userDB.userDao().getUsers() - Log.d("Sign-up",user.toString()) + override fun onFailure(call: Call, t: Throwable) { + Log.d("SignUp-Failure", t.message.toString()) + } + }) + Log.d("SignUpActivity", "All Finished") - Toast.makeText(this,"회원가입이 완료되었습니다.",Toast.LENGTH_SHORT).show() - return + return true } } \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/User.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/User.kt index 017dfb8..24f6039 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/User.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/User.kt @@ -2,11 +2,19 @@ package com.example.umc_6th import androidx.room.Entity import androidx.room.PrimaryKey +import com.google.gson.annotations.SerializedName +import java.io.Serial @Entity(tableName = "UserTable") data class User( + @SerializedName("email") var email : String, - var password : String + + @SerializedName("password") + var password : String, + + @SerializedName("name") + var name : String ){ @PrimaryKey(autoGenerate = true) var id : Int = 0 } From e75c7014a401908e5eaef2560677ca3de88c7746 Mon Sep 17 00:00:00 2001 From: BAEK0111 Date: Tue, 25 Jun 2024 01:15:13 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[simba/#47]=20feat::=20Login=20API=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/umc_6th/AuthApi.kt | 3 ++ .../java/com/example/umc_6th/AuthService.kt | 53 +++++++++++++++++++ .../java/com/example/umc_6th/BaseResponse.kt | 14 +++-- .../java/com/example/umc_6th/LoginActivity.kt | 30 +++++++---- .../java/com/example/umc_6th/LoginView.kt | 6 +++ .../java/com/example/umc_6th/MainActivity.kt | 7 +++ .../com/example/umc_6th/SignUpActivity.kt | 31 +++++------ .../java/com/example/umc_6th/SignUpView.kt | 6 +++ 8 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/AuthService.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/LoginView.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/SignUpView.kt diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt index 9d75a39..61ba302 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/AuthApi.kt @@ -7,4 +7,7 @@ import retrofit2.http.POST interface AuthApi { @POST("/users") fun signUp(@Body user : User) : Call + + @POST("/users/login") + fun login(@Body user : User) : Call } \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/AuthService.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/AuthService.kt new file mode 100644 index 0000000..3f04204 --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/AuthService.kt @@ -0,0 +1,53 @@ +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 { + override fun onResponse(call: Call, response: Response) { + 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, 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 { + override fun onResponse(call: Call, response: Response) { + 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, t: Throwable) { + Log.d("Login-Failure", t.message.toString()) + } + }) + Log.d("LoginActivity", "All Finished") + } +} \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt index 2ce028f..c642468 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/BaseResponse.kt @@ -1,7 +1,15 @@ package com.example.umc_6th +import com.google.gson.annotations.SerializedName + data class BaseResponse( - val isSuccess : Boolean, - val code : Int, - val message : String + @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 +) \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/LoginActivity.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/LoginActivity.kt index 8052100..1ba3a04 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/LoginActivity.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/LoginActivity.kt @@ -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 { lateinit var binding : ActivityLoginBinding @@ -38,16 +38,10 @@ class LoginActivity:AppCompatActivity() { val email : String = binding.loginIdEt.text.toString() + "@" + binding.loginDirectInputEt.text.toString() val pwd : String = binding.loginPasswordEt.text.toString() - val songDB = SongDatabase.getInstance(this)!! - val user = songDB.userDao().getUser(email, pwd) + val authService = AuthService() + authService.setLoginView(this) - if (user != null) { - Log.d("LoginActivity", user.id.toString()) - saveJwt(user.id) - startMainActivity() - } else { - Toast.makeText(this, "회원 정보가 존재하지 않습니다", Toast.LENGTH_SHORT).show() - } + authService.login(User(email, pwd, "")) } private fun startMainActivity() { @@ -62,4 +56,20 @@ class LoginActivity:AppCompatActivity() { editor.apply() } + private fun saveJwtFromServer(jwt : String) { + val spf = getSharedPreferences("auth2", MODE_PRIVATE) + val editor = spf.edit() + + editor.putString("jwt", jwt) + editor.apply() + } + + override fun onLoginSuccess(code: Int, result: Result) { + saveJwtFromServer(result.jwt) + startMainActivity() + } + override fun onLoginFailure(message: String) { + + } + } \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/LoginView.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/LoginView.kt new file mode 100644 index 0000000..ec0c20f --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/LoginView.kt @@ -0,0 +1,6 @@ +package com.example.umc_6th + +interface LoginView { + fun onLoginSuccess(code : Int, result : Result) + fun onLoginFailure(message : String) +} \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/MainActivity.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/MainActivity.kt index 89b9be8..9649418 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/MainActivity.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/MainActivity.kt @@ -54,6 +54,13 @@ class MainActivity : AppCompatActivity() { startActivity(intent) activityResultLauncher.launch(intent) } + Log.d("MainActivity",getJwt().toString()) + } + + private fun getJwt(): String? { + val spf = this.getSharedPreferences("auth2", MODE_PRIVATE) + + return spf!!.getString("jwt","") } override fun onResume() { diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt index f6b05ae..6b89b76 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpActivity.kt @@ -10,7 +10,7 @@ import retrofit2.Call import retrofit2.Callback import retrofit2.Response -class SignUpActivity : AppCompatActivity(){ +class SignUpActivity : AppCompatActivity(), SignUpView{ lateinit var binding : ActivitySignupBinding @@ -47,26 +47,19 @@ class SignUpActivity : AppCompatActivity(){ return false } - RetrofitInstance.authApi.signUp(getUser()).enqueue(object: Callback { - override fun onResponse(call: Call, response: Response) { - Log.d("SignUp-Success", response.toString()) - val response : BaseResponse = response.body()!! - when(response.code) { - 1000 -> finish() // 성공 - 2016, 2018 -> { - binding.signUpEmailErrorTv.visibility = View.VISIBLE - binding.signUpEmailErrorTv.text = response.message - } - } + val authService = AuthService() + authService.setSignUpView(this) // 객체를 통한 멤버 함수 호출 - } + authService.signUp(getUser()) + return true + } - override fun onFailure(call: Call, t: Throwable) { - Log.d("SignUp-Failure", t.message.toString()) - } - }) - Log.d("SignUpActivity", "All Finished") + override fun onSignUpSuccess() { + finish() + } - return true + override fun onSignUpFailure(message: String) { + binding.signUpEmailErrorTv.visibility = View.VISIBLE + binding.signUpEmailErrorTv.text = message } } \ No newline at end of file diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpView.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpView.kt new file mode 100644 index 0000000..1d08efc --- /dev/null +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/SignUpView.kt @@ -0,0 +1,6 @@ +package com.example.umc_6th + +interface SignUpView { + fun onSignUpSuccess() + fun onSignUpFailure(message : String) +} \ No newline at end of file From e6eecd25c2305f583fdc2b9db45703b226756bd6 Mon Sep 17 00:00:00 2001 From: BAEK0111 Date: Tue, 25 Jun 2024 01:52:36 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[simba/#47]=20feat::=209=EC=A3=BC=EC=B0=A8?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/umc_6th/LookFragment.kt | 99 +-- .../main/java/com/example/umc_6th/LookView.kt | 7 + .../com/example/umc_6th/RetrofitInstance.kt | 1 + .../main/java/com/example/umc_6th/SongApi.kt | 9 + .../java/com/example/umc_6th/SongRVAdapter.kt | 56 ++ .../java/com/example/umc_6th/SongResponse.kt | 22 + .../java/com/example/umc_6th/SongService.kt | 40 + .../app/src/main/res/layout/fragment_look.xml | 726 ++++++++++++------ UMC_6th/app/src/main/res/layout/item_song.xml | 71 ++ 9 files changed, 707 insertions(+), 324 deletions(-) create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/LookView.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/SongApi.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/SongRVAdapter.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/SongResponse.kt create mode 100644 UMC_6th/app/src/main/java/com/example/umc_6th/SongService.kt create mode 100644 UMC_6th/app/src/main/res/layout/item_song.xml diff --git a/UMC_6th/app/src/main/java/com/example/umc_6th/LookFragment.kt b/UMC_6th/app/src/main/java/com/example/umc_6th/LookFragment.kt index 4e86200..db6b993 100644 --- a/UMC_6th/app/src/main/java/com/example/umc_6th/LookFragment.kt +++ b/UMC_6th/app/src/main/java/com/example/umc_6th/LookFragment.kt @@ -1,4 +1,5 @@ import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -7,36 +8,20 @@ import android.widget.ScrollView import android.widget.TextView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager +import com.example.umc_6th.FloChartResult import com.example.umc_6th.LockerAlbumRVAdapter +import com.example.umc_6th.LookView import com.example.umc_6th.R import com.example.umc_6th.Song import com.example.umc_6th.SongDatabase +import com.example.umc_6th.SongRVAdapter +import com.example.umc_6th.SongService import com.example.umc_6th.databinding.FragmentLookBinding -class LookFragment : Fragment() { +class LookFragment : Fragment(),LookView { lateinit var binding: FragmentLookBinding - private lateinit var songDB: SongDatabase - - private lateinit var chartBtn : Button - private lateinit var videoBtn : Button - private lateinit var genreBtn : Button - private lateinit var situationBtn : Button - private lateinit var audioBtn : Button - private lateinit var atmosphereBtn : Button - - private lateinit var buttonList: List