diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 61d8a1f..5c76f99 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="deploymentTargetDropDown"> - <targetSelectedWithDropDown> + <runningDeviceTargetSelectedWithDropDown> <Target> - <type value="QUICK_BOOT_TARGET" /> + <type value="RUNNING_DEVICE_TARGET" /> <deviceKey> <Key> <type value="VIRTUAL_DEVICE_PATH" /> @@ -11,7 +11,7 @@ </Key> </deviceKey> </Target> - </targetSelectedWithDropDown> - <timeTargetWasSelectedWithDropDown value="2023-03-21T05:50:26.695170200Z" /> + </runningDeviceTargetSelectedWithDropDown> + <timeTargetWasSelectedWithDropDown value="2023-03-23T12:21:45.633470700Z" /> </component> </project> \ No newline at end of file diff --git a/buddy/build.gradle b/buddy/build.gradle index 3349531..6eb2563 100644 --- a/buddy/build.gradle +++ b/buddy/build.gradle @@ -44,10 +44,8 @@ dependencies { api project(path: ':common-ui') implementation 'io.github.ParkSangGwon:tedimagepicker:1.2.8' - implementation 'de.hdodenhof:circleimageview:3.1.0' - // Navigation api "androidx.navigation:navigation-fragment-ktx:$rootProject.nav_version" api "androidx.navigation:navigation-ui-ktx:$rootProject.nav_version" @@ -55,7 +53,7 @@ dependencies { implementation "com.google.dagger:hilt-android:$rootProject.hiltVersion" kapt "com.google.dagger:hilt-android-compiler:$rootProject.hiltVersion" - implementation 'androidx.core:core-ktx:1.7.0' + implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' testImplementation 'junit:junit:4.13.2' diff --git a/buddy/src/main/AndroidManifest.xml b/buddy/src/main/AndroidManifest.xml index a5918e6..a880029 100644 --- a/buddy/src/main/AndroidManifest.xml +++ b/buddy/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> - + <uses-permission android:name="android.permission.INTERNET" /> </manifest> \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/data/BuddyService.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/data/BuddyService.kt new file mode 100644 index 0000000..f49a346 --- /dev/null +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/data/BuddyService.kt @@ -0,0 +1,43 @@ +package com.nocapstone.buddyvet.buddy.data + +import com.nocapstone.buddyvet.buddy.domain.entity.* +import com.nocapstone.common.data.dto.CommonResponse +import okhttp3.MultipartBody +import retrofit2.http.* + +interface BuddyService { + + @GET("buddies") + suspend fun readBuddyList( + @Header("Authorization") token: String + ): CommonResponse<BuddyListResponse> + + @POST("buddies") + suspend fun createBuddy( + @Header("Authorization") token: String, + @Body buddyRequest: BuddyRequest + ): CommonResponse<BuddyId> + + @GET("buddies/{buddyId}") + suspend fun readBuddyDetail( + @Header("Authorization") token: String, + @Path("buddyId") buddyId: Long, + ): CommonResponse<BuddyDetailResponse> + + //TODO Refactor PATCH + + + @DELETE("buddies/{buddyId}") + suspend fun deleteBuddy( + @Header("Authorization") token: String, + @Path("buddyId") buddyId: Long, + ): CommonResponse<String?> + + @POST("buddies/{buddyId}/image") + suspend fun uploadBuddyImg( + @Header("Authorization") token: String, + @Path("buddyId") buddyId: Long, + @Part image: MultipartBody.Part + ): CommonResponse<String?> + +} \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/di/NetworkModule.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/di/NetworkModule.kt new file mode 100644 index 0000000..234eca1 --- /dev/null +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/di/NetworkModule.kt @@ -0,0 +1,22 @@ +package com.nocapstone.buddyvet.buddy.di + +import com.nocapstone.buddyvet.buddy.data.BuddyService +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import retrofit2.Retrofit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class NetworkModule { + + @Singleton + @Provides + fun provideBuddyService(retrofit: Retrofit): BuddyService { + return retrofit.create(BuddyService::class.java) + } + + +} \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/entity/BuddyData.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/entity/BuddyData.kt new file mode 100644 index 0000000..d61b416 --- /dev/null +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/entity/BuddyData.kt @@ -0,0 +1,32 @@ +package com.nocapstone.buddyvet.buddy.domain.entity + +data class BuddyListResponse( + val buddies: List<BuddyData>? +) + +data class BuddyData( + val id: Int, + val kind: String, + val name: String, + val gender: String, + val profile: String, + val age: String +) + +data class BuddyId( + val buddyId: Long +) + +data class BuddyDetailResponse( + val buddy: BuddyDetailData +) + +data class BuddyDetailData( + val kind: String, + val name: String, + val profile: String, + val birthDay: String, + val adoptDay: String, + val isNeutered: Boolean, + val gender: String +) diff --git a/onboarding/src/main/java/com/nocapstone/onboarding/domain/BuddyRequest.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/entity/BuddyRequest.kt similarity index 75% rename from onboarding/src/main/java/com/nocapstone/onboarding/domain/BuddyRequest.kt rename to buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/entity/BuddyRequest.kt index 46c93b3..06b9c51 100644 --- a/onboarding/src/main/java/com/nocapstone/onboarding/domain/BuddyRequest.kt +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/entity/BuddyRequest.kt @@ -1,9 +1,8 @@ -package com.nocapstone.onboarding.domain +package com.nocapstone.buddyvet.buddy.domain.entity data class BuddyRequest( val kind : String, var name : String = "name", - var bread : String = "bread", var birthDay : String = "birthday", var adoptDay : String = "adoptDay", var isNeutered : Boolean = false, diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/usecase/BuddyUseCase.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/usecase/BuddyUseCase.kt new file mode 100644 index 0000000..ff5b350 --- /dev/null +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/domain/usecase/BuddyUseCase.kt @@ -0,0 +1,33 @@ +package com.nocapstone.buddyvet.buddy.domain.usecase + +import com.nocapstone.buddyvet.buddy.data.BuddyService +import com.nocapstone.buddyvet.buddy.domain.entity.BuddyData +import com.nocapstone.buddyvet.buddy.domain.entity.BuddyRequest +import okhttp3.MultipartBody +import javax.inject.Inject + +class BuddyUseCase @Inject constructor( + private val buddyService: BuddyService +) { + + suspend fun readBuddyList(token: String): List<BuddyData>? { + return buddyService.readBuddyList(token).data.buddies + } + + suspend fun createBuddy(token: String, buddyRequest: BuddyRequest): Long { + return buddyService.createBuddy(token, buddyRequest).data.buddyId + } + + suspend fun readBuddyDetail(token: String, buddyId: Long) { + buddyService.readBuddyDetail(token, buddyId) + } + + suspend fun deleteBuddy(token: String, buddyId: Long) { + buddyService.deleteBuddy(token, buddyId) + } + + suspend fun uploadBuddyImg(token: String, buddyId: Long, image: MultipartBody.Part) { + buddyService.uploadBuddyImg(token, buddyId, image) + } + +} \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/BuddyViewModel.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/BuddyViewModel.kt index 1ca2075..740159e 100644 --- a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/BuddyViewModel.kt +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/BuddyViewModel.kt @@ -1,25 +1,133 @@ package com.nocapstone.buddyvet.buddy.ui +import android.content.Context +import android.net.Uri +import android.provider.OpenableColumns +import android.util.Log import androidx.lifecycle.ViewModel -import com.nocapstone.buddyvet.buddy.util.BuddyType +import androidx.lifecycle.viewModelScope +import com.nocapstone.buddyvet.buddy.domain.entity.BuddyData +import com.nocapstone.buddyvet.buddy.domain.entity.BuddyRequest +import com.nocapstone.buddyvet.buddy.domain.usecase.BuddyUseCase +import com.nocapstone.common.domain.usecase.DataStoreUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.toRequestBody +import javax.inject.Inject -class BuddyViewModel : ViewModel() { - private val _selectType = MutableStateFlow(BuddyType.NULL) - val selectType: StateFlow<BuddyType> = _selectType +@HiltViewModel +class BuddyViewModel @Inject constructor( + @ApplicationContext private val context: Context, + private val buddyUseCase: BuddyUseCase, + private val dataStoreUseCase: DataStoreUseCase +) : ViewModel() { + + private val _buddyList = MutableStateFlow<List<BuddyData>?>(null) + val buddyList: StateFlow<List<BuddyData>?> = _buddyList - /* private val _newBuddy = MutableStateFlow<BuddyRequest?>(null) - val newBuddy : StateFlow<BuddyRequest?> = _newBuddy - */ - - fun setSelectBuddyType(buddyType : BuddyType){ - if (_selectType.value == buddyType){ - _selectType.value = BuddyType.NULL - }else{ - //_newBuddy.value = BuddyRequest(buddyType.kind) - _selectType.value = buddyType + val newBuddy: StateFlow<BuddyRequest?> = _newBuddy + + private val _selectImgUri = MutableStateFlow<Uri?>(null) + val selectImgUri: StateFlow<Uri?> = _selectImgUri + + fun setKind(kind: String) { + _newBuddy.value = BuddyRequest(kind) + } + + fun setName(name: String) { + _newBuddy.value?.name = name + } + + fun setBirthDay(birthDay: String) { + _newBuddy.value?.birthDay = birthDay + } + + fun setAdoptDay(adoptDay: String) { + _newBuddy.value?.adoptDay = adoptDay + } + + fun setNeutered(Neutered: Boolean) { + _newBuddy.value?.isNeutered = Neutered + } + + fun setGender(gender: String) { + if (gender == "남자") { + _newBuddy.value?.gender = "M" + } else { + _newBuddy.value?.gender = "W" + } + } + + fun setSelectImgUri(uri: Uri?) { + _selectImgUri.value = uri + } + + fun readBuddyList() { + viewModelScope.launch { + val jwt = dataStoreUseCase.bearerJsonWebToken.first()!! + _buddyList.value = buddyUseCase.readBuddyList(jwt) } } + + fun createBuddy() { + viewModelScope.launch { + try { + val jwt = dataStoreUseCase.bearerJsonWebToken.first()!! + val buddyId = buddyUseCase.createBuddy(jwt, _newBuddy.value!!) + if (_selectImgUri.value != null) { + uploadBuddyImg(jwt, buddyId) + } + } catch (e: Exception) { + Log.d("createBuddy", e.message.toString()) + } + } + } + + fun readBuddyDetail(buddyId: Long) { + viewModelScope.launch { + val jwt = dataStoreUseCase.bearerJsonWebToken.first()!! + buddyUseCase.readBuddyDetail(jwt, buddyId) + } + } + + fun deleteBuddy(buddyId: Long) { + viewModelScope.launch { + val jwt = dataStoreUseCase.bearerJsonWebToken.first()!! + buddyUseCase.deleteBuddy(jwt, buddyId) + } + } + + private fun uploadBuddyImg(token: String, buddyId: Long) { + viewModelScope.launch { + val imgUri = _selectImgUri.value!! + val inputStream = context.contentResolver.openInputStream(imgUri) + val byteArray = inputStream!!.readBytes() + val requestBody = byteArray.toRequestBody("multipart/form-data".toMediaTypeOrNull()) + val image = MultipartBody.Part.createFormData( + "image", + getFileName(context, imgUri), + requestBody + ) + buddyUseCase.uploadBuddyImg(token, buddyId, image) + } + } + + + private fun getFileName(context: Context, uri: Uri): String? { + val cursor = context.contentResolver.query(uri, null, null, null, null) + return cursor?.use { + it.moveToFirst() + val nameIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME) + return it.getString(nameIndex) + } + } + + } \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/CompleteRegistrationFragment.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/CompleteRegistrationFragment.kt index 39dfee9..0c4ac0c 100644 --- a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/CompleteRegistrationFragment.kt +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/CompleteRegistrationFragment.kt @@ -22,12 +22,10 @@ class CompleteRegistrationFragment : Fragment() { private val buddyViewModel: BuddyViewModel by viewModels({ requireActivity() }) - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - // Inflate the layout for this fragment _binding = FragmentCompleteRegistrationBinding.inflate(inflater, container, false) return binding.root } @@ -35,7 +33,13 @@ class CompleteRegistrationFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.apply { + this.viewModel = buddyViewModel + this.lifecycleOwner = viewLifecycleOwner + } + binding.next.setOnClickListener { + buddyViewModel.createBuddy() LoginUtil.startMainActivity(requireActivity(), mainActivityClass) } diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfo2Fragment.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfo2Fragment.kt deleted file mode 100644 index 28f8101..0000000 --- a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfo2Fragment.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.nocapstone.buddyvet.buddy.ui - -import android.os.Bundle -import androidx.fragment.app.Fragment -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.viewModels -import androidx.navigation.fragment.findNavController -import com.nocapstone.buddyvet.buddy.R -import com.nocapstone.buddyvet.buddy.databinding.FragmentInputBuddyInfo2Binding -import dagger.hilt.android.AndroidEntryPoint - - -@AndroidEntryPoint -class InputBuddyInfo2Fragment : Fragment() { - - private var _binding: FragmentInputBuddyInfo2Binding? = null - private val binding get() = _binding!! - - private val buddyViewModel: BuddyViewModel by viewModels({ requireActivity() }) - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - // Inflate the layout for this fragment - _binding = FragmentInputBuddyInfo2Binding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding.next.setOnClickListener { - findNavController().navigate(R.id.next) - } - - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - - -} \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfoFragment.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfoFragment.kt index 05190d2..def4514 100644 --- a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfoFragment.kt +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyInfoFragment.kt @@ -1,6 +1,7 @@ package com.nocapstone.buddyvet.buddy.ui import android.os.Bundle +import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View @@ -10,8 +11,12 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.nocapstone.buddyvet.buddy.R import com.nocapstone.buddyvet.buddy.databinding.FragmentInputBuddyInfoBinding -import com.nocapstone.buddyvet.buddy.util.BuddyType +import com.nocapstone.common_ui.CalendarUtil +import com.nocapstone.common_ui.DialogForDatePicker +import com.nocapstone.common_ui.R.layout.list_item import dagger.hilt.android.AndroidEntryPoint +import gun0912.tedimagepicker.builder.TedImagePicker +import java.lang.reflect.GenericArrayType @AndroidEntryPoint @@ -19,9 +24,9 @@ class InputBuddyInfoFragment : Fragment() { private var _binding: FragmentInputBuddyInfoBinding? = null private val binding get() = _binding!! - private val buddyViewModel: BuddyViewModel by viewModels({ requireActivity() }) - + private val neuteredItem = listOf("예", "아니오") + private val genderListItem = listOf("남자", "여자") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -33,31 +38,77 @@ class InputBuddyInfoFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val breedListItem = if (buddyViewModel.selectType.value == BuddyType.DOG) { - resources.getStringArray(com.nocapstone.common.R.array.DogBreed) - } else { - resources.getStringArray(com.nocapstone.common.R.array.CatBreed) - } - - val breadAdapter = ArrayAdapter( + val neuteredAdapter = ArrayAdapter( requireContext(), - com.nocapstone.common_ui.R.layout.list_item, - breedListItem + list_item, + neuteredItem ) - binding.breedTv.setAdapter(breadAdapter) + val genderAdapter = ArrayAdapter( requireContext(), - com.nocapstone.common_ui.R.layout.list_item, - listOf("남자", "여자", "없음") + list_item, + genderListItem ) - binding.genderTv.setAdapter(genderAdapter) + + with(binding) { + viewModel = buddyViewModel + lifecycleOwner = viewLifecycleOwner + genderTv.setAdapter(genderAdapter) + isNeuteredTv.setAdapter(neuteredAdapter) + birthDayTv.text = CalendarUtil.getTodayDate() + adoptDayTv.text = CalendarUtil.getTodayDate() + birthDayTv.setOnClickListener { + DialogForDatePicker.Builder(requireContext()) + .setInitDate(CalendarUtil.parseStringToDate(binding.birthDayTv.text.toString())!!) + .setOnClickPositiveButton { newDate -> + binding.birthDayTv.text = CalendarUtil.parseDateToFormatString(newDate) + } + .build().show() + } + adoptDayTv.setOnClickListener { + DialogForDatePicker.Builder(requireContext()) + .setInitDate(CalendarUtil.parseStringToDate(binding.adoptDayTv.text.toString())!!) + .setOnClickPositiveButton { newDate -> + binding.adoptDayTv.text = CalendarUtil.parseDateToFormatString(newDate) + } + .build().show() + } + imgSelect.setOnClickListener { + TedImagePicker.with(requireContext()) + .start { + buddyViewModel.setSelectImgUri(it) + } + } + } binding.next.setOnClickListener { + setData() findNavController().navigate(R.id.next) } } + private fun setData() { + with(binding) { + buddyViewModel.setName(nameTv.text.toString()) + buddyViewModel.setNeutered( + when (isNeuteredTv.text.toString()) { + neuteredItem[0] -> true + else -> false + } + ) + buddyViewModel.setGender( + when (genderTv.text.toString()) { + genderListItem[0] -> "M" + else -> "W" + } + ) + buddyViewModel.setAdoptDay(adoptDayTv.text.toString()) + buddyViewModel.setBirthDay(birthDayTv.text.toString()) + } + + } + override fun onDestroyView() { super.onDestroyView() @@ -65,5 +116,4 @@ class InputBuddyInfoFragment : Fragment() { } - } \ No newline at end of file diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyTypeFragment.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyTypeFragment.kt index 85198aa..9818e5b 100644 --- a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyTypeFragment.kt +++ b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/ui/InputBuddyTypeFragment.kt @@ -9,7 +9,6 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.nocapstone.buddyvet.buddy.R import com.nocapstone.buddyvet.buddy.databinding.FragmentInputBuddyTypeBinding -import com.nocapstone.buddyvet.buddy.util.BuddyType import dagger.hilt.android.AndroidEntryPoint @@ -37,11 +36,11 @@ class InputBuddyTypeFragment : Fragment() { binding.lifecycleOwner = viewLifecycleOwner binding.dogIv.setOnClickListener { - buddyViewModel.setSelectBuddyType(BuddyType.DOG) + buddyViewModel.setKind("D") } binding.catIv.setOnClickListener { - buddyViewModel.setSelectBuddyType(BuddyType.CAT) + buddyViewModel.setKind("C") } binding.next.setOnClickListener { diff --git a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/util/Enum.kt b/buddy/src/main/java/com/nocapstone/buddyvet/buddy/util/Enum.kt deleted file mode 100644 index 3cb7bd7..0000000 --- a/buddy/src/main/java/com/nocapstone/buddyvet/buddy/util/Enum.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.nocapstone.buddyvet.buddy.util - -enum class BuddyType(val kind : String) { - NULL(""),DOG("D"), CAT("C") -} \ No newline at end of file diff --git a/buddy/src/main/res/layout/fragment_complete_registration.xml b/buddy/src/main/res/layout/fragment_complete_registration.xml index d711519..2cf38d4 100644 --- a/buddy/src/main/res/layout/fragment_complete_registration.xml +++ b/buddy/src/main/res/layout/fragment_complete_registration.xml @@ -1,8 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<layout xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:android="http://schemas.android.com/apk/res/android" +<layout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> + <data> + + <variable + name="viewModel" + type="com.nocapstone.buddyvet.buddy.ui.BuddyViewModel" /> + </data> + <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" @@ -10,13 +17,95 @@ tools:context="com.nocapstone.buddyvet.buddy.ui.CompleteRegistrationFragment"> + <TextView + android:id="@+id/complete_tv" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:fontFamily="@font/cafe24_ssurround_air" + android:gravity="center" + android:text="이대로 등록 할까" + android:textColor="@color/black" + android:textSize="32sp" + android:textStyle="bold" + app:layout_constraintTop_toTopOf="parent" /> + + + <de.hdodenhof.circleimageview.CircleImageView + android:id="@+id/profile_iv" + uri="@{viewModel.selectImgUri}" + android:layout_width="65dp" + android:layout_height="65dp" + android:layout_marginTop="32dp" + app:civ_border_overlay="true" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/complete_tv" /> + + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:gravity="center" + android:orientation="vertical" + app:layout_constraintTop_toBottomOf="@id/profile_iv"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:fontFamily="@font/cafe24_ssurround" + android:text="@{viewModel.newBuddy.name}" + android:textColor="@color/black" + android:textSize="17sp" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:fontFamily="@font/cafe24_ssurround" + android:text='@{viewModel.newBuddy.gender == "M" ? "남아" : "여아"}' + android:textColor="@color/black" + android:textSize="17sp" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:fontFamily="@font/cafe24_ssurround" + android:text='@{"중성화 여부 : " + (viewModel.newBuddy.neutered ? "O" : "X")}' + android:textColor="@color/black" + android:textSize="17sp" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:fontFamily="@font/cafe24_ssurround" + android:text='@{"태어난 날 : " + viewModel.newBuddy.birthDay}' + android:textColor="@color/black" + android:textSize="17sp" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:fontFamily="@font/cafe24_ssurround" + android:text='@{"가족이 된 날 : " + viewModel.newBuddy.adoptDay}' + android:textColor="@color/black" + android:textSize="17sp" /> + + </LinearLayout> + + <com.google.android.material.button.MaterialButton android:id="@+id/next" style="@style/basic_btn" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginBottom="@dimen/basic_bottom_btn_margin_non_padding" - android:text="다음" + android:text="등록하기" android:textSize="@dimen/basic_btn_textSize" app:backgroundTint="@color/butter" app:layout_constraintBottom_toBottomOf="parent" /> diff --git a/buddy/src/main/res/layout/fragment_input_buddy_info.xml b/buddy/src/main/res/layout/fragment_input_buddy_info.xml index 377a9e8..8d35736 100644 --- a/buddy/src/main/res/layout/fragment_input_buddy_info.xml +++ b/buddy/src/main/res/layout/fragment_input_buddy_info.xml @@ -6,8 +6,10 @@ <data> <variable - name="imageUri" - type="String" /> + name="viewModel" + type="com.nocapstone.buddyvet.buddy.ui.BuddyViewModel" /> + + </data> <androidx.constraintlayout.widget.ConstraintLayout @@ -40,11 +42,10 @@ <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/main_iv" - photoUrl="@{imageUri}" + uri="@{viewModel.selectImgUri}" android:layout_width="65dp" android:layout_height="65dp" - app:civ_border_overlay="true" - tools:src="@drawable/img_person" /> + app:civ_border_overlay="true" /> <ImageView android:layout_width="wrap_content" @@ -67,15 +68,18 @@ app:layout_constraintTop_toBottomOf="@id/img_select"> <com.google.android.material.textfield.TextInputEditText + android:id="@+id/name_tv" android:layout_width="match_parent" android:layout_height="wrap_content" /> </com.google.android.material.textfield.TextInputLayout> <LinearLayout + android:id="@+id/info1_lo" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" + android:orientation="horizontal" app:layout_constraintTop_toBottomOf="@+id/name_et"> <com.google.android.material.textfield.TextInputLayout @@ -84,12 +88,12 @@ android:layout_height="100dp" android:layout_marginEnd="16dp" android:layout_weight="1" - android:hint="종류" + android:hint="성별" app:boxStrokeColor="@color/butter" app:hintTextColor="@color/black"> <AutoCompleteTextView - android:id="@+id/breed_tv" + android:id="@+id/gender_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="none" /> @@ -102,20 +106,94 @@ android:layout_width="0dp" android:layout_height="100dp" android:layout_weight="1" - android:hint="성별" + android:hint="중성화" app:boxStrokeColor="@color/butter" app:hintTextColor="@color/black"> <AutoCompleteTextView - android:id="@+id/gender_tv" + android:id="@+id/isNeutered_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="none" /> - </com.google.android.material.textfield.TextInputLayout> + </LinearLayout> + + <LinearLayout + android:id="@+id/info2_lo" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="16dp" + android:orientation="horizontal" + app:layout_constraintTop_toBottomOf="@+id/info1_lo"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="32dp" + android:layout_weight="1" + android:gravity="start" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:text="태어난 날" + android:textSize="17sp" /> + + <TextView + android:id="@+id/adoptDay_tv" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:drawablePadding="16dp" + android:fontFamily="@font/cafe24_ssurround" + android:gravity="end|bottom" + android:textColor="@color/black" + android:textSize="17sp" + app:drawableEndCompat="@drawable/img_calendar" + app:layout_constraintStart_toStartOf="@id/title" + app:layout_constraintTop_toTopOf="parent" /> + + </LinearLayout> + + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="start" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:text="처음 만난 날" + android:textSize="17sp" /> + + <TextView + android:id="@+id/birthDay_tv" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:drawablePadding="16dp" + android:fontFamily="@font/cafe24_ssurround" + android:gravity="end|bottom" + android:textColor="@color/black" + android:textSize="17sp" + app:drawableEndCompat="@drawable/img_calendar" + app:layout_constraintStart_toStartOf="@id/title" + app:layout_constraintTop_toTopOf="parent" /> + + </LinearLayout> + + + </LinearLayout> + + <com.google.android.material.button.MaterialButton android:id="@+id/next" style="@style/basic_btn" diff --git a/buddy/src/main/res/layout/fragment_input_buddy_info2.xml b/buddy/src/main/res/layout/fragment_input_buddy_info2.xml deleted file mode 100644 index e27b327..0000000 --- a/buddy/src/main/res/layout/fragment_input_buddy_info2.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<layout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools"> - - <androidx.constraintlayout.widget.ConstraintLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:padding="21dp" - tools:context="com.nocapstone.buddyvet.buddy.ui.InputBuddyInfoFragment"> - - - - <com.google.android.material.button.MaterialButton - android:id="@+id/next" - style="@style/basic_btn" - android:layout_width="match_parent" - android:layout_height="50dp" - android:layout_marginBottom="@dimen/basic_bottom_btn_margin_non_padding" - android:text="다음" - android:textSize="@dimen/basic_btn_textSize" - app:backgroundTint="@color/butter" - app:layout_constraintBottom_toBottomOf="parent" /> - - </androidx.constraintlayout.widget.ConstraintLayout> - -</layout> diff --git a/buddy/src/main/res/layout/fragment_input_buddy_type.xml b/buddy/src/main/res/layout/fragment_input_buddy_type.xml index 1dd352e..e2c9d3b 100644 --- a/buddy/src/main/res/layout/fragment_input_buddy_type.xml +++ b/buddy/src/main/res/layout/fragment_input_buddy_type.xml @@ -6,8 +6,6 @@ <data> - <import type="com.nocapstone.buddyvet.buddy.util.BuddyType" /> - <variable name="viewModel" type="com.nocapstone.buddyvet.buddy.ui.BuddyViewModel" /> @@ -54,7 +52,7 @@ android:layout_height="100dp" android:layout_gravity="center" android:elevation="16dp" - app:cardBackgroundColor="@{viewModel.selectType == BuddyType.DOG ? @color/butter : @color/white}" + app:cardBackgroundColor='@{viewModel.newBuddy.kind.equals("D")? @color/butter : @color/white}' app:cardCornerRadius="50dp"> <ImageView @@ -90,7 +88,7 @@ android:layout_height="100dp" android:layout_gravity="center" android:elevation="16dp" - app:cardBackgroundColor="@{viewModel.selectType == BuddyType.CAT ? @color/butter : @color/white}" + app:cardBackgroundColor='@{viewModel.newBuddy.kind.equals("C")? @color/butter : @color/white}' app:cardCornerRadius="50dp"> diff --git a/buddy/src/main/res/navigation/nav_buddy.xml b/buddy/src/main/res/navigation/nav_buddy.xml index c8251d5..fdc1354 100644 --- a/buddy/src/main/res/navigation/nav_buddy.xml +++ b/buddy/src/main/res/navigation/nav_buddy.xml @@ -20,14 +20,6 @@ android:id="@+id/inputBuddyInfoFragment" android:name="com.nocapstone.buddyvet.buddy.ui.InputBuddyInfoFragment" android:label="InputBuddyInfoFragment" > - <action - android:id="@+id/next" - app:destination="@id/inputBuddyInfo2Fragment" /> - </fragment> - <fragment - android:id="@+id/inputBuddyInfo2Fragment" - android:name="com.nocapstone.buddyvet.buddy.ui.InputBuddyInfo2Fragment" - android:label="InputBuddyInfo2Fragment" > <action android:id="@+id/next" app:destination="@id/completeRegistrationFragment" /> diff --git a/common-ui/src/main/java/com/nocapstone/common_ui/BindingAdapter.kt b/common-ui/src/main/java/com/nocapstone/common_ui/BindingAdapter.kt index f7cbf09..be5c3ec 100644 --- a/common-ui/src/main/java/com/nocapstone/common_ui/BindingAdapter.kt +++ b/common-ui/src/main/java/com/nocapstone/common_ui/BindingAdapter.kt @@ -1,6 +1,8 @@ package com.nocapstone.common_ui +import android.graphics.drawable.Drawable import android.net.Uri +import android.util.Log import android.view.View import android.widget.ImageView import androidx.databinding.BindingAdapter @@ -8,6 +10,9 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import de.hdodenhof.circleimageview.CircleImageView @BindingAdapter("photoUrl") @@ -22,10 +27,10 @@ fun bindImageView(imageView: ImageView, photoUrl: String?) { fun bindImageView(imageView: ImageView, uri: Uri?) { Glide.with(imageView.context) .load(uri) + .placeholder(R.drawable.img_person) .into(imageView) } - @BindingAdapter("adapter", "submitList", requireAll = true) fun bindViewPager(view: ViewPager2, adapter: RecyclerView.Adapter<*>, submitList: List<Any>?) { if (submitList == null) return diff --git a/common-ui/src/main/res/drawable/img_calendar.xml b/common-ui/src/main/res/drawable/img_calendar.xml new file mode 100644 index 0000000..6141ea6 --- /dev/null +++ b/common-ui/src/main/res/drawable/img_calendar.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#8F8378" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,4h-1V2h-2v2H8V2H6v2H5C3.89,4 3.01,4.9 3.01,6L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V6C21,4.9 20.1,4 19,4zM19,20H5V10h14V20zM9,14H7v-2h2V14zM13,14h-2v-2h2V14zM17,14h-2v-2h2V14zM9,18H7v-2h2V18zM13,18h-2v-2h2V18zM17,18h-2v-2h2V18z"/> +</vector> diff --git a/common/src/main/java/com/nocapstone/common/domain/usecase/AuthUseCase.kt b/common/src/main/java/com/nocapstone/common/domain/usecase/AuthUseCase.kt index 3c3b158..6aba545 100644 --- a/common/src/main/java/com/nocapstone/common/domain/usecase/AuthUseCase.kt +++ b/common/src/main/java/com/nocapstone/common/domain/usecase/AuthUseCase.kt @@ -11,9 +11,8 @@ import javax.inject.Inject class AuthUseCase @Inject constructor( private val authService: AuthService ){ - suspend fun login(token: String, providerType: String= "KAKAO") : Response<LoginResponse> { - val jwt = authService.postToken(LoginRequest(token, providerType)) - return jwt + suspend fun login(token: String, providerType: String = "KAKAO"): Response<LoginResponse> { + return authService.postToken(LoginRequest(token, providerType)) } suspend fun inputUserInfo(token:String , nickname: String){ diff --git a/diary/build.gradle b/diary/build.gradle index d24a073..6b90152 100644 --- a/diary/build.gradle +++ b/diary/build.gradle @@ -39,15 +39,15 @@ android { dependencies { + api project(path: ':common-ui') + api project(path: ':common') + implementation 'io.github.ParkSangGwon:tedimagepicker:1.2.8' // Navigation api "androidx.navigation:navigation-fragment-ktx:$rootProject.nav_version" api "androidx.navigation:navigation-ui-ktx:$rootProject.nav_version" - api project(path: ':common-ui') - api project(path: ':common') - implementation "com.google.dagger:hilt-android:$rootProject.hiltVersion" kapt "com.google.dagger:hilt-android-compiler:$rootProject.hiltVersion" diff --git a/onboarding/src/main/java/com/nocapstone/onboarding/ui/InputUserInfoFragment.kt b/onboarding/src/main/java/com/nocapstone/onboarding/ui/InputUserInfoFragment.kt index e38e72f..a723f3d 100644 --- a/onboarding/src/main/java/com/nocapstone/onboarding/ui/InputUserInfoFragment.kt +++ b/onboarding/src/main/java/com/nocapstone/onboarding/ui/InputUserInfoFragment.kt @@ -7,7 +7,6 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController -import com.nocapstone.common_ui.MainActivityUtil import com.nocapstone.onboarding.R import com.nocapstone.onboarding.databinding.FragmentInputUserInfoBinding import dagger.hilt.android.AndroidEntryPoint @@ -32,13 +31,11 @@ class InputUserInfoFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding.next.setOnClickListener { splashViewModel.postUserInfo(binding.nameEt.toString()) findNavController().navigate(R.id.next) } } - override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/onboarding/src/main/java/com/nocapstone/onboarding/ui/SplashViewModel.kt b/onboarding/src/main/java/com/nocapstone/onboarding/ui/SplashViewModel.kt index 36b516f..dd25d47 100644 --- a/onboarding/src/main/java/com/nocapstone/onboarding/ui/SplashViewModel.kt +++ b/onboarding/src/main/java/com/nocapstone/onboarding/ui/SplashViewModel.kt @@ -1,15 +1,11 @@ package com.nocapstone.onboarding.ui -import android.content.Context -import android.net.Uri import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.nocapstone.common.domain.usecase.AuthUseCase import com.nocapstone.common.domain.usecase.DataStoreUseCase -import com.nocapstone.onboarding.domain.BuddyRequest import dagger.hilt.android.lifecycle.HiltViewModel -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject @@ -20,17 +16,11 @@ class SplashViewModel @Inject constructor( private val dataStoreUseCase: DataStoreUseCase ) : ViewModel() { - - - - fun withJsonWebToken(callback: (String?) -> Unit) { viewModelScope.launch { callback.invoke(dataStoreUseCase.bearerJsonWebToken.firstOrNull()) } } - - fun signup(token: String, createCallback: () -> Unit, loginCallback: () -> Unit) { createCallback.invoke() @@ -51,13 +41,12 @@ class SplashViewModel @Inject constructor( // } } - fun postUserInfo(nickname: String) { viewModelScope.launch { try { authUseCase.inputUserInfo(dataStoreUseCase.bearerJsonWebToken.first()!!, nickname) } catch (e: Exception) { - Log.d("postTest", e.message.toString()) + Log.d("nickNameApi", e.message.toString()) } } }