From f3232c13ed7b02d4e3f380183baf5a1c796d513f Mon Sep 17 00:00:00 2001 From: SYAAINN Date: Mon, 29 Apr 2024 10:30:51 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=204=EC=A3=BC=EC=B0=A8=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=20=ED=86=B5=EC=8B=A0=20=EC=8B=A4=EC=8A=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 22 ++++- app/src/main/AndroidManifest.xml | 5 ++ .../com/sopt/now/activity/MainActivity.kt | 10 +-- .../com/sopt/now/activity/SignInActivity.kt | 12 +-- .../com/sopt/now/activity/SignUpActivity.kt | 90 +++++++++++-------- .../main/java/com/sopt/now/data/ApiFactory.kt | 25 ++++++ .../java/com/sopt/now/data/AuthService.kt | 12 +++ .../com/sopt/now/data/RequestSignUpDto.kt | 16 ++++ .../com/sopt/now/data/ResponseSignUpDto.kt | 12 +++ .../sopt/now/homeFragment/HomeViewModel.kt | 22 ++--- .../sopt/now/homeFragment/HomeViewObject.kt | 9 +- .../homeViewHolder/FriendViewHolder.kt | 2 +- .../homeViewHolder/MyProfileViewHolder.kt | 2 +- .../sopt/now/myPageFragment/MyPageFragment.kt | 6 +- app/src/main/res/layout/activity_signup.xml | 10 +-- app/src/main/res/layout/fragment_mypage.xml | 8 +- app/src/main/res/layout/item_friend.xml | 4 +- app/src/main/res/layout/item_myprofile.xml | 2 +- app/src/main/res/values/strings.xml | 6 +- 19 files changed, 189 insertions(+), 86 deletions(-) create mode 100644 app/src/main/java/com/sopt/now/data/ApiFactory.kt create mode 100644 app/src/main/java/com/sopt/now/data/AuthService.kt create mode 100644 app/src/main/java/com/sopt/now/data/RequestSignUpDto.kt create mode 100644 app/src/main/java/com/sopt/now/data/ResponseSignUpDto.kt diff --git a/app/build.gradle b/app/build.gradle index b189c4f..e8c80e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,12 @@ plugins { id 'com.android.application' + id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.0' id 'org.jetbrains.kotlin.android' } +Properties properties = new Properties() +properties.load(project.rootProject.file('local.properties').newDataInputStream()) + android { namespace 'com.sopt.now' compileSdk 34 @@ -15,6 +19,8 @@ android { versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + buildConfigField "String", "AUTH_BASE_URL", properties["base.url"] } buildTypes { @@ -33,6 +39,8 @@ android { buildFeatures { viewBinding true + + buildConfig true } } @@ -48,9 +56,21 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' -// ViewModel 의존성 설정 + // ViewModel 의존성 설정 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" implementation "androidx.fragment:fragment-ktx:1.6.1" implementation "androidx.activity:activity-ktx:1.8.0" + + // Network + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1' + implementation 'com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0' + + // define a BOM and its version + implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0")) + +// define any required OkHttp artifacts without version + implementation("com.squareup.okhttp3:okhttp") + implementation("com.squareup.okhttp3:logging-interceptor") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 110a3f6..efc78f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,10 @@ + + + + { val homeFragment = HomeFragment().apply { arguments = Bundle().apply { putString("Name", userName) - putString("Place", userPlace) + putString("Place", userPhoneNumber) } } replaceFragment(HomeFragment()) @@ -55,7 +55,7 @@ class MainActivity : AppCompatActivity() { putString("ID", userId) putString("PW", userPw) putString("Name", userName) - putString("Place", userPlace) + putString("PhoneNumber", userPhoneNumber) } } replaceFragment(myPageFragment) diff --git a/app/src/main/java/com/sopt/now/activity/SignInActivity.kt b/app/src/main/java/com/sopt/now/activity/SignInActivity.kt index 55c1f0a..fa3cb5e 100644 --- a/app/src/main/java/com/sopt/now/activity/SignInActivity.kt +++ b/app/src/main/java/com/sopt/now/activity/SignInActivity.kt @@ -17,10 +17,10 @@ class SignInActivity : AppCompatActivity() { val userId = intent.getStringExtra("ID") val userPw = intent.getStringExtra("PW") val userName = intent.getStringExtra("Name") - val userPlace = intent.getStringExtra("Place") + val userPhoneNumber = intent.getStringExtra("PhoneNumber") binding.btnSignInSignIn.setOnClickListener { - isSignInValid(userId, userPw, userName, userPlace) + isSignInValid(userId, userPw, userName, userPhoneNumber) } binding.btnSignInSignUp.setOnClickListener { @@ -29,7 +29,7 @@ class SignInActivity : AppCompatActivity() { } } - private fun isSignInValid(userId: String?, userPw: String?, userName: String?, userPlace: String?) { + private fun isSignInValid(userId: String?, userPw: String?, userName: String?, userPhoneNumber: String?) { when { binding.etSignInId.text.toString() != userId -> { showToast(getString(R.string.toast_SignInActivity_InvalidId)) @@ -39,7 +39,7 @@ class SignInActivity : AppCompatActivity() { } else -> { showToast(getString(R.string.toast_SignInActivity_ValidSignIn)) - navigateToMainActivity(userId, userPw, userName, userPlace) + navigateToMainActivity(userId, userPw, userName, userPhoneNumber) } } } @@ -48,12 +48,12 @@ class SignInActivity : AppCompatActivity() { Toast.makeText(this, message, Toast.LENGTH_SHORT).show() } - private fun navigateToMainActivity(userId: String?, userPw: String?, userName: String?, userPlace: String?) { + private fun navigateToMainActivity(userId: String?, userPw: String?, userName: String?, userPhoneNumber: String?) { val intent = Intent(this, MainActivity::class.java) intent.putExtra("ID", userId) intent.putExtra("PW", userPw) intent.putExtra("Name", userName) - intent.putExtra("Place", userPlace) + intent.putExtra("PhoneNumber", userPhoneNumber) startActivity(intent) } } diff --git a/app/src/main/java/com/sopt/now/activity/SignUpActivity.kt b/app/src/main/java/com/sopt/now/activity/SignUpActivity.kt index a04a1cf..0d8999e 100644 --- a/app/src/main/java/com/sopt/now/activity/SignUpActivity.kt +++ b/app/src/main/java/com/sopt/now/activity/SignUpActivity.kt @@ -1,63 +1,75 @@ package com.sopt.now.activity -import android.content.Intent import android.os.Bundle +import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import com.sopt.now.R +import com.sopt.now.data.RequestSignUpDto +import com.sopt.now.data.ResponseSignUpDto +import com.sopt.now.data.ServicePool import com.sopt.now.databinding.ActivitySignupBinding +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response class SignUpActivity : AppCompatActivity() { - private lateinit var binding: ActivitySignupBinding - - val ID_MIN_LENGTH = 6 - val ID_MAX_LENGTH = 10 - val PW_MIN_LENGTH = 8 - val PW_MAX_LENGTH = 12 + private val binding by lazy { ActivitySignupBinding.inflate(layoutInflater) } + private val authService by lazy { ServicePool.authService } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = ActivitySignupBinding.inflate(layoutInflater) setContentView(binding.root) + initViews() + } + private fun initViews() { binding.btnSignUpSignUp.setOnClickListener { - isSignUpValid() + signUp() } } - private fun isSignUpValid() { - - val id = binding.etSignUpId.text.toString() - val pw = binding.etSignUpPw.text.toString() - val name = binding.etSignUpName.text.toString() - val place = binding.etSignUpPlace.text.toString() - - when { - id.isEmpty() || pw.isEmpty() || name.isEmpty() || place.isEmpty() -> { - showToast(getString(R.string.toast_SignUpActivity_InvalidSignUp_Blank)) + private fun signUp() { + val signUpRequest = getSignUpRequestDto() + authService.signUp(signUpRequest).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response, + ) { + if (response.isSuccessful) { + val data: ResponseSignUpDto? = response.body() + val userId = response.headers()["location"] + Toast.makeText( + this@SignUpActivity, + "회원가입 성공 유저의 ID는 $userId 입니둥", + Toast.LENGTH_SHORT, + ).show() + Log.d("SignUp", "data: $data, userId: $userId") + } else { + val error = response.message() + Toast.makeText( + this@SignUpActivity, + "로그인이 실패 $error", + Toast.LENGTH_SHORT, + ).show() + } } - id.length !in ID_MIN_LENGTH..ID_MAX_LENGTH || pw.length !in PW_MIN_LENGTH..PW_MAX_LENGTH -> { - showToast(getString(R.string.toast_SignUpActivity_InvalidSignUp_Blank)) + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText(this@SignUpActivity, "서버 에러 발생 ", Toast.LENGTH_SHORT).show() } - - else -> { - showToast(getString(R.string.toast_SignUpActivity_ValidSignUp)) - navigateToSignInActivity() - } - } + }) } - private fun showToast(message: String) { - Toast.makeText(this, message, Toast.LENGTH_SHORT).show() - } - - private fun navigateToSignInActivity() { - val intent = Intent(this, SignInActivity::class.java) - intent.putExtra("ID", binding.etSignUpId.text.toString()) - intent.putExtra("PW", binding.etSignUpPw.text.toString()) - intent.putExtra("Name", binding.etSignUpName.text.toString()) - intent.putExtra("Place", binding.etSignUpPlace.text.toString()) - startActivity(intent) + private fun getSignUpRequestDto(): RequestSignUpDto { + val id = binding.etSignUpId.text.toString() + val password = binding.etSignUpPw.text.toString() + val nickname = binding.etSignUpName.text.toString() + val phoneNumber = binding.etSignUpPhoneNumber.text.toString() + return RequestSignUpDto( + authenticationId = id, + password = password, + nickname = nickname, + phone = phoneNumber + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/data/ApiFactory.kt b/app/src/main/java/com/sopt/now/data/ApiFactory.kt new file mode 100644 index 0000000..00744dc --- /dev/null +++ b/app/src/main/java/com/sopt/now/data/ApiFactory.kt @@ -0,0 +1,25 @@ +package com.sopt.now.data + +import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory +import com.sopt.now.BuildConfig +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import retrofit2.Retrofit + + +object ApiFactory { + private const val BASE_URL: String = BuildConfig.AUTH_BASE_URL + + val retrofit: Retrofit by lazy { + Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) + .build() + } + + inline fun create(): T = retrofit.create(T::class.java) +} + +object ServicePool { + val authService = ApiFactory.create() +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/data/AuthService.kt b/app/src/main/java/com/sopt/now/data/AuthService.kt new file mode 100644 index 0000000..a20c2b4 --- /dev/null +++ b/app/src/main/java/com/sopt/now/data/AuthService.kt @@ -0,0 +1,12 @@ +package com.sopt.now.data + +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.POST + +interface AuthService { + @POST("member/join") + fun signUp( + @Body request: RequestSignUpDto, + ): Call +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/data/RequestSignUpDto.kt b/app/src/main/java/com/sopt/now/data/RequestSignUpDto.kt new file mode 100644 index 0000000..4db251b --- /dev/null +++ b/app/src/main/java/com/sopt/now/data/RequestSignUpDto.kt @@ -0,0 +1,16 @@ +package com.sopt.now.data + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RequestSignUpDto( + @SerialName("authenticationId") + val authenticationId: String, + @SerialName("password") + val password: String, + @SerialName("nickname") + val nickname: String, + @SerialName("phone") + val phone: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/data/ResponseSignUpDto.kt b/app/src/main/java/com/sopt/now/data/ResponseSignUpDto.kt new file mode 100644 index 0000000..e05cd1c --- /dev/null +++ b/app/src/main/java/com/sopt/now/data/ResponseSignUpDto.kt @@ -0,0 +1,12 @@ +package com.sopt.now.data + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseSignUpDto( + @SerialName("code") + val status: Int, + @SerialName("message") + val message: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/homeFragment/HomeViewModel.kt b/app/src/main/java/com/sopt/now/homeFragment/HomeViewModel.kt index 8884ec9..2678d51 100644 --- a/app/src/main/java/com/sopt/now/homeFragment/HomeViewModel.kt +++ b/app/src/main/java/com/sopt/now/homeFragment/HomeViewModel.kt @@ -8,7 +8,7 @@ class HomeViewModel : ViewModel() { val mockMyProfile = HomeViewObject.MyProfile( profileImage = R.drawable.sonminjae_profile, name = "Son minjae", - place = "Korea, Seoul", + phoneNumber = "Korea, Seoul", selfDescription = "i can win", enable = true, ) @@ -16,61 +16,61 @@ class HomeViewModel : ViewModel() { HomeViewObject.FriendProfile( profileImage = R.drawable.michaeljordan_profile, name = "Michael jordan", - place = "USA, Chicago", + phoneNumber = "USA, Chicago", selfDescription = "I'm the GOAT", ), HomeViewObject.FriendProfile( profileImage = R.drawable.stephcurry_profile, name = "Steph Curry", - place = "USA, San Francisco", + phoneNumber = "USA, San Francisco", selfDescription = "I can shoot with ma eyes closed", ), HomeViewObject.FriendProfile( profileImage = R.drawable.nikolajokic_profile, name = "Nikola Jokic", - place = "USA, Denver", + phoneNumber = "USA, Denver", selfDescription = "Basketball? It's EEEEEasy", ), HomeViewObject.FriendProfile( profileImage = R.drawable.lukadoncic_profile, name = "Luka Doncic", - place = "USA, Dallas", + phoneNumber = "USA, Dallas", selfDescription = "Love you, Kyle" ), HomeViewObject.FriendProfile( profileImage = R.drawable.lebronjames_profile, name = "Lebron James", - place = "USA, Los Angeles", + phoneNumber = "USA, Los Angeles", selfDescription = "I'm the real GOAT" ), HomeViewObject.FriendProfile( profileImage = R.drawable.kevindurant_profile, name = "Kevin Durant", - place = "USA, Phoenix", + phoneNumber = "USA, Phoenix", selfDescription = "2 CHAMPS, 2 MVP. That's it" ), HomeViewObject.FriendProfile( profileImage = R.drawable.jimmybutler_profile, name = "Jimmy Butler", - place = "USA, Miami", + phoneNumber = "USA, Miami", selfDescription = "I NEED RINGS" ), HomeViewObject.FriendProfile( profileImage = R.drawable.dirknowitzki_profile, name = "Dirk Nowitzki", - place = "USA, Dallas", + phoneNumber = "USA, Dallas", selfDescription = "Have you heard about German Wunderkind?" ), HomeViewObject.FriendProfile( profileImage = R.drawable.demianlillard_profile, name = "Demian Lillard", - place = "USA, Portland", + phoneNumber = "USA, Portland", selfDescription = "It's DAME TIME." ), HomeViewObject.FriendProfile( profileImage = R.drawable.charlesbarkley_profile, name = "Charles Barkley", - place = "USA, Philadelphia", + phoneNumber = "USA, Philadelphia", selfDescription = "CHUCK CHUCK" ) ) diff --git a/app/src/main/java/com/sopt/now/homeFragment/HomeViewObject.kt b/app/src/main/java/com/sopt/now/homeFragment/HomeViewObject.kt index d58dd5d..2aae879 100644 --- a/app/src/main/java/com/sopt/now/homeFragment/HomeViewObject.kt +++ b/app/src/main/java/com/sopt/now/homeFragment/HomeViewObject.kt @@ -6,14 +6,15 @@ sealed class HomeViewObject { data class MyProfile( @DrawableRes val profileImage: Int, val name: String, - val place: String, + val phoneNumber: String, val selfDescription: String, val enable: Boolean, - ) + ) : HomeViewObject() + data class FriendProfile( @DrawableRes val profileImage: Int, val name: String, - val place: String, + val phoneNumber: String, val selfDescription: String, - ) + ) : HomeViewObject() } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/FriendViewHolder.kt b/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/FriendViewHolder.kt index 867b67b..b5e2a14 100644 --- a/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/FriendViewHolder.kt +++ b/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/FriendViewHolder.kt @@ -11,7 +11,7 @@ class FriendViewHolder(private val binding: ItemFriendBinding) : binding.run { ivFriendProfile.setImageResource(friendData.profileImage) tvFriendName.text = friendData.name - tvFriendPlace.text = friendData.place + tvFriendPhoneNumber.text = friendData.phoneNumber tvFriendSelfDescription.text = friendData.selfDescription } } diff --git a/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/MyProfileViewHolder.kt b/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/MyProfileViewHolder.kt index 168b3ba..232b8fc 100644 --- a/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/MyProfileViewHolder.kt +++ b/app/src/main/java/com/sopt/now/homeFragment/homeViewHolder/MyProfileViewHolder.kt @@ -11,7 +11,7 @@ class MyProfileViewHolder(private val binding: ItemMyprofileBinding) : binding.run { ivMyProfileProfile.setImageResource(myProfileData.profileImage) tvMyProfileName.text = myProfileData.name - tvMyProfilePlace.text = myProfileData.place + tvMyProfilePhoneNumber.text = myProfileData.phoneNumber tvMyProfileSelfDescription.text = myProfileData.selfDescription switchMyProfileEnable } diff --git a/app/src/main/java/com/sopt/now/myPageFragment/MyPageFragment.kt b/app/src/main/java/com/sopt/now/myPageFragment/MyPageFragment.kt index 66bf8ab..4424800 100644 --- a/app/src/main/java/com/sopt/now/myPageFragment/MyPageFragment.kt +++ b/app/src/main/java/com/sopt/now/myPageFragment/MyPageFragment.kt @@ -17,7 +17,7 @@ class MyPageFragment : Fragment() { private var userId: String? = null private var userPw: String? = null private var userName: String? = null - private var userPlace: String? = null + private var userPhoneNumber: String? = null override fun onCreateView( inflater: LayoutInflater, @@ -28,7 +28,7 @@ class MyPageFragment : Fragment() { userId = arguments?.getString("ID") userPw = arguments?.getString("PW") userName = arguments?.getString("Name") - userPlace = arguments?.getString("Place") + userPhoneNumber = arguments?.getString("PhoneNumber") return binding.root } @@ -38,7 +38,7 @@ class MyPageFragment : Fragment() { binding.tvMyPageShowId.text = userId binding.tvMyPageShowPw.text = userPw binding.tvMyPageShowName.text = userName - binding.tvMyPageShowPlace.text = userPlace + binding.tvMyPageShowPhoneNumber.text = userPhoneNumber } override fun onDestroyView() { diff --git a/app/src/main/res/layout/activity_signup.xml b/app/src/main/res/layout/activity_signup.xml index 9debf1f..1697b0b 100644 --- a/app/src/main/res/layout/activity_signup.xml +++ b/app/src/main/res/layout/activity_signup.xml @@ -79,24 +79,24 @@ app:layout_constraintTop_toBottomOf="@+id/tvSignUpName" /> + android:hint="@string/et_SignUp_PhoneNumber" + app:layout_constraintTop_toBottomOf="@+id/tvSignUpPhoneNumber" />